web-dev-qa-db-fra.com

Comment tester quel Shell j'utilise dans un terminal?

Comment vérifier quel Shell j'utilise dans un terminal? Quel est le Shell que j'utilise sous MacOS?

73
user5837

Plusieurs façons, du plus fiable au moins (et du plus lourd au moins "lourd"):

  1. ps -p$$ -ocmd=. (Sous Solaris, il peut être nécessaire que ce soit fname au lieu de cmd. Sous OSX et BSD, il devrait être command au lieu de cmd.)
  2. Vérifier $BASH_VERSION, $ZSH_VERSION, et d'autres variables spécifiques à Shell.
  3. Vérifier $Shell; ceci est un dernier recours, car il spécifie votre par défaut Shell et pas nécessairement le actuel Shell.
75
geekosaur

J'ai constaté que les éléments suivants fonctionnent dans les quatre shells que j'ai installés sur mon système (bash, dash, zsh, csh):

$ ps -p $$

Les éléments suivants fonctionnent sur zsh, bash et dash, mais pas sur csh:

$ echo $0
43
Steven D

Comme la question demande le Shell utilisé et ne parle pas des arguments potentiels qui lui sont transmis, voici un moyen d'éviter de les montrer:

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

Remarque sur certaines implémentations plus légères (téléphones Android, busybox, etc.): ps ne prend pas toujours en charge le -p switch, mais vous pouvez effectuer la recherche avec une commande comme ps | grep "^$$ ". (Cette grep expression régulière identifiera de manière unique le PID, il n'y aura donc pas de faux positifs.

6
palswim

Il y a deux façons vraiment simples:

  • Utilisation de la commande ps :

    ps -o comm= $$
    

    ou

    ps -h -o comm -p $$
    

    où:

    • -h ou terminer toutes les options avec = pour ne pas afficher d'en-tête.
    • -o comm pour afficher uniquement le nom de base du processus (bash au lieu de /bin/bash).
    • -p <PID> processus de liste uniquement avec liste de formulaires PID fournie.
  • Utilisation du système de pseudo-fichier (/proc d'informations sur le processus:

    cat /proc/$$/comm
    

    Cette option se comporte exactement comme la commande ps ci-dessus.

    ou

    readlink /proc/$$/exe
    

    Cette /proc/PID/exe liens vers le fichier en cours d'exécution, qui dans ce cas pointerait vers/bin/bash,/bin/ksh, etc.

    Pour obtenir uniquement le nom du Shell, vous pouvez simplement utiliser

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

    C'est la seule option qui donnera toujours le même résultat même si vous êtes dans un script, du code source ou un terminal, en tant que liens vers le binaire de l'interpréteur Shell utilisé.

    Avertissement Vous devez savoir que cela affichera le binaire ultime, donc ksh peut être lié à ksh93 ou sh à bash.

L'utilisation de /proc est vraiment utile via le /proc/self, qui renvoie au PID de la commande en cours.

5
David Goitia

Un mélange de toutes les autres réponses, compatible avec Mac (comm), Solaris (fname) et Linux (cmd):

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

Si vous l'avez enregistré dans vos variables d'environnement, vous pouvez utiliser ce qui suit:

echo $Shell
2
jasonleonhard

Le pid du Shell en cours d'exécution est donné par la var $$ (dans la plupart des shells).

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

Utilisation de backticks pour faire fonctionner jsh (Heirlomm Shell).

Dans de nombreux obus, le test direct de ps -o args= -p $$ fonctionne, mais busybox ash échoue (résolu).

La vérification que $1 doit être égal à $$ supprime la plupart des faux positifs.

Le dernier ;: sont utilisés pour maintenir le shell en cours d'exécution pour ksh et zsh.

Des tests sur plus de systèmes vous aideront, veuillez faire un commentaire si cela ne fonctionne pas pour vous.

Ne fonctionne pas dans les types de shells csh.

1
user79743

J'ai mis $MYSHELL pour de futurs tests dans mon Shell-agnostique ~/.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 section tcsh est probablement imprudente de rouler dans un script de style POSIX car elle est si radicalement différente (donc l'avertissement et la pause de cinq secondes). (D'une part, les shells de style csh ne peuvent pas faire 2>/dev/null ou >&2, comme indiqué dans le fameux Csh Programming Considered Harmful rant.)

0
Adam Katz