Come testare quale shell sto usando in un terminale?


69

Come verificare quale shell sto usando in un terminale? Qual è la shell che sto usando in MacOS?


2
@xenoterracide: almeno unix.stackexchange.com/questions/3645/… . La risposta di geekosaur è più completa, quindi ho votato per chiudere la domanda precedente.
Gilles 'SO-smetti di essere malvagio' il

1
echo $ SHELL, no?
mondo innocente,

@ innocent-world No, echo #SHELLnon è proprio così. Vedi # 3 nella Risposta di geekosaur .
Basil Bourque,

Non sono così sicuro che "shell" abbia un significato ben definito. Ad esempio, potresti correre xterm -e /bin/cat ma non sono contento di chiamare /bin/catuna shell.
Basile Starynkevitch,

Anche alcune shell (come scsh ) non usano la shell POSIX come sintassi.
Basile Starynkevitch

Risposte:


71

Diversi modi, dal più al meno affidabile (e dal più al meno "pesante"):

  1. ps -p$$ -ocmd=. (Su Solaris, potrebbe essere necessario che sia fnameinvece di cmd. Su OSX e su BSD dovrebbe essere commandinvece di cmd.)
  2. Verificare la presenza di $BASH_VERSION, $ZSH_VERSIONe altre variabili specifiche della shell.
  3. Controllare $SHELL; questa è l'ultima risorsa, in quanto specifica la shell predefinita e non necessariamente la shell corrente .

4
Dovresti menzionarlo $0anche tu ?
Mikel,

Non mi piace $0perché è più complicato: (1) potrebbe essere solo il nome di base, (2) potrebbe avere "-" sul davanti per designarlo come una shell di login.
Geekosaur,

ps -p$$ -ocmd=""è più bello :-)
asoundmove il

1
@geekosaur: forse è così, ma $0sembra ancora più utile di $SHELL: non sei d'accordo? Puoi sempre reindirizzarlo sedper rimuovere '-'.
iconoclasta,

2
Se si sta eseguendo tcsh, $tcshe $versionverrà impostata. Queste sono variabili della shell, non variabili d'ambiente. Se stai eseguendo una versione non tcsh di csh, non credo ci siano variabili distintive. E ovviamente la sintassi usata per controllare le variabili differisce tra csh / tcsh da un lato e sh / ksh / bash / zsh dall'altro.
Keith Thompson,

41

Ho scoperto che i seguenti lavori nelle quattro shell che ho installato sul mio sistema (bash, dash, zsh, csh):

$ ps -p $$

Quanto segue funziona su zsh, bash e dash, ma non su csh:

$ echo $0

2
Inoltre non funziona sui pesci.
Ron E

Penso che la risposta di @ jiliagre sia probabilmente la userei oggi. Sul pesce %selfpuò essere usato al posto di$$
Steven D

8

Poiché la domanda richiede la shell utilizzata e non parla dei potenziali argomenti passati ad essa, ecco un modo che evita di mostrarli:

$ ps -o comm= -p $$
ksh93 

6

Una nota su alcune implementazioni più leggere (telefoni Android, busybox, ecc.): psNon sempre ha il supporto per lo -pswitch, ma puoi eseguire la ricerca con un comando come ps | grep "^$$ ". (Questa grepregex identificherà in modo univoco il PID, quindi non ci saranno falsi positivi.


7
ps | grep $$può ancora dare falsi positivi se, ad esempio, il tuo processo attuale è 1234e c'è un processo 12345.
Keith Thompson,

4

Ci sono due modi davvero semplici:

  • Utilizzando il comando ps :

    ps -o comm= $$

    o

    ps -h -o comm -p $$

    dove:

    • -ho terminando tutte le opzioni con =per non mostrare alcuna intestazione.
    • -o commper mostrare solo il nome del processo ( bashanziché /bin/bash).
    • -p <PID> elenca solo il processo con l'elenco dei moduli PID fornito.
  • Utilizzando lo pseudo-file system delle informazioni di processo / proc :

    cat /proc/$$/comm

    Questa opzione si comporta esattamente come il pscomando sopra.

    o

    readlink /proc/$$/exe

    Questo si /proc/PID/execollega al file in esecuzione, che in questo caso punterebbe a / bin / bash, / bin / ksh, ecc.

    Per ottenere solo il nome della shell puoi semplicemente usare

    basename $(readlink /proc/$$/exe)

    Questa è l'unica opzione che fornirà sempre lo stesso risultato anche se ci si trova in uno script, codice sorgente o terminale, come collegamenti al binario dell'interprete shell in uso.

    Avvertimento Devi essere consapevole che questo mostrerà l'ultimo binario, quindi ksh potrebbe essere collegato a ksh93 o da sh a bash.

L'utilizzo di /procè davvero utile tramite il /proc/self, che si collega al PID del comando corrente.


3

Un mix di tutte le altre risposte, compatibile con Mac (comm), Solaris (fname) e Linux (cmd):

ps -p$$ -o cmd="",comm="",fname="" 2>/dev/null | sed 's/^-//' | grep -oE '\w+' | head -n1

questo mi dà il mio attuale nome di directory; inoltre, sotto cshe tcshmi dàAmbiguous output redirect.
iconoclasta

2

Se lo hai salvato nelle variabili di ambiente, puoi utilizzare quanto segue:

echo $SHELL

Molto probabilmente restituirà il percorso dell'eseguibile della shell della shell di accesso. Non è certo però che la shell di login sia quella attualmente in esecuzione.
Kusalananda

1

Il pid della shell in esecuzione è dato da var $$ (nella maggior parte delle shell).

whichsh="`ps -o pid,args| awk '$1=='"$$"'{print $2}'`"
echo "$whichsh"

Usare i backtick per far funzionare jsh (Heirlomm shell).

In molte shell il test diretto ps -o args= -p $$funziona, ma busybox ashfallisce (risolto).

Il controllo che $1deve essere uguale a $$rimuove la maggior parte dei falsi positivi.

Gli ultimi ;:sono usati per mantenere la shell in esecuzione per ksh e zsh.

I test su più sistemi ti aiuteranno, per favore fai un commento se non funziona per te.

Non funziona nel cshtipo di shell.


Su OS / X, nei miei test, ottengo almeno 3 righe, una per la shell, una per /usr/lib/dyld, una per /private/var/db/dyld/dyld_shared_cache_x86_64.
Stéphane Chazelas,

Sì, ora seleziona solo le voci in / bin e / usr / bin
Stéphane Chazelas

@ StéphaneChazelas Forse è meglio adesso?

0

Ho impostato $MYSHELLper i test futuri nel mio shell-agnostico ~/.aliases:

unset MYSHELL
if [ -n "$ZSH_VERSION" ] && type zstyle >/dev/null 2>&1; then        # zsh
  MYSHELL=`command -v zsh`
elif [ -x "$BASH" ] && shopt -q >/dev/null 2>&1; then                # bash
  MYSHELL=`command -v bash`
elif [ -x "$shell" ] && which setenv |grep builtin >/dev/null; then  # tcsh
  echo "DANGER: this script is likely not compatible with C shells!"
  sleep 5
  setenv MYSHELL "$shell"
fi

# verify
if [ ! -x "$MYSHELL" ]; then
  MYSHELL=`command -v "$(ps $$ |awk 'NR == 2 { print $NF }')"`
  [ -x "$MYSHELL" ] || MYSHELL="${SHELL:-/bin/sh}"  # default if verify fails
fi

La tcshsezione è probabilmente saggio a rotolare in uno script POSIX-style dal momento che è così radicalmente diversa (quindi l'avvertimento e cinque secondi di pausa). (Per uno, le cshshell in stile non possono fare 2>/dev/nullo >&2, come notato nella famosa programmazione Csh considerata dannosa .)


-1

Puoi semplicemente usare il echo $0comando per verificare quale shell stai usando e <name_of_the_shell> --versionper verificare la versione della shell. (es. bash --version).


Steven D l'ha già menzionato
:)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.