it-swarm.it

Come testare quale Shell sto usando in un terminale?

Come verificare quale Shell sto usando in un terminale? Che cos'è la Shell che sto usando in MacOS?

73
user5837

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

  1. ps -p$$ -ocmd=. (Su Solaris, potrebbe essere necessario che sia fname anziché cmd. Su OSX e su BSD dovrebbe essere command invece di cmd.)
  2. Controlla $BASH_VERSION, $ZSH_VERSION e altre variabili specifiche della shell.
  3. Dai un'occhiata $Shell; questa è l'ultima risorsa, in quanto specifica la shell impostazione predefinita e non necessariamente la shell corrente.
75
geekosaur

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
43
Steven D

Poiché la domanda richiede l'utilizzo della shell e non parla dei potenziali argomenti passati, ecco un modo per evitare di mostrarli:

$ ps -o comm= -p $$
ksh93 
8
jlliagre

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

6
palswim

Ci sono due modi davvero semplici:

  • Usando ps comando:

    ps -o comm= $$
    

    o

    ps -h -o comm -p $$
    

    dove:

    • -h o finendo tutte le opzioni con = per non mostrare alcuna intestazione.
    • -o comm per mostrare solo il processo basename (bash invece di /bin/bash).
    • -p <PID> elenca solo il processo con l'elenco dei moduli PID fornito.
  • Utilizzando il pseudo-file /proc informazioni di processo pseudo-file:

    cat /proc/$$/comm
    

    Questa opzione si comporta esattamente come il comando ps sopra.

    o

    readlink /proc/$$/exe
    

    Questo /proc/PID/exe si collega al file in esecuzione, che in questo caso farebbe riferimento a/bin/bash,/bin/ksh, ecc.

    Per ottenere solo il nome di Shell puoi semplicemente usare

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

    Questa è l'unica opzione che darà 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.

    Avviso Devi essere consapevole che questo mostrerà l'ultimo binario, quindi ksh può essere collegato a ksh93 o sh a bash.

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

5
David Goitia

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
3
sebastien

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

echo $Shell
2
jasonleonhard

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 di ps -o args= -p $$ funziona, ma busybox ash fallisce (risolto).

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

L'ultimo ;: sono usati per mantenere 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 tipo di shell csh.

1
user79743

Ho impostato $MYSHELL per futuri test 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

È improbabile che la sezione tcsh si trasformi in uno script in stile POSIX poiché è così radicalmente diverso (quindi l'avviso e la pausa di cinque secondi). (Ad esempio, le shell in stile csh non possono fare 2>/dev/null o >&2, come notato nel famoso Programmazione Csh considerata dannosa rant.)

0
Adam Katz