Comment tester quel shell j'utilise dans un terminal?

69

Comment vérifier quel shell j'utilise dans un terminal? Quelle est la coque que j'utilise sous MacOS?

utilisateur5837
la source
2
@xenoterracide: au moins unix.stackexchange.com/questions/3645/… . La réponse de geekosaur étant plus complète, j'ai voté en faveur de la fermeture de la question précédente.
Gilles, arrête de faire le mal
1
echo $ SHELL, non?
innocent-world
@ innocent-world Non, ce echo #SHELLn'est pas tout à fait ça. Voir le numéro 3 dans la réponse de geekosaur .
Basil Bourque
Je ne suis pas sûr que "shell" ait un sens bien défini. Par exemple, vous pouvez courir xterm -e /bin/cat mais je ne suis pas content d’appeler /bin/catun shell.
Basile Starynkevitch
De plus, certains shells (comme scsh ) n'utilisent pas le shell POSIX comme la syntaxe.
Basile Starynkevitch

Réponses:

71

Plusieurs manières, du plus au moins fiable (et du plus au moins "lourd"):

  1. ps -p$$ -ocmd=. (Sous Solaris, il se peut que cela doive être à la fnameplace de cmd. Sous OSX et sous BSD, à la commandplace de cmd.)
  2. Vérifiez pour $BASH_VERSION, $ZSH_VERSIONet d'autres variables spécifiques au shell.
  3. Chèque $SHELL; c'est un dernier recours, car il spécifie votre shell par défaut et pas nécessairement le shell actuel .
geekosaur
la source
4
Devez vous mentionner $0aussi?
Mikel
Je n'aime pas $0parce que c'est plus compliqué: (1) il peut s'agir simplement du nom de base, (2) il peut avoir '-' sur le devant pour le désigner comme un shell de connexion.
geekosaur
ps -p$$ -ocmd=""est plus jolie :-)
asoundmove
1
@geekosaur: peut-être, mais $0semble quand même plus utile que $SHELL: ne êtes-vous pas d'accord? Vous pouvez toujours le faire passer sedpour supprimer le "-".
iconoclaste
2
Si vous courez tcsh, $tcshet $versionsera réglé. Ce sont des variables shell, pas des variables d'environnement. Si vous utilisez une version non-tcsh de csh, je ne pense pas qu'il existe des variables distinctives. Et bien sûr, la syntaxe utilisée pour vérifier les variables diffère entre csh / tcsh d'une part et sh / ksh / bash / zsh de l'autre.
Keith Thompson
41

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

$ ps -p $$

Ce qui suit fonctionne sur zsh, bash et dash, mais pas sur csh:

$ echo $0
Steven D
la source
2
Aussi ne fonctionne pas sur le poisson.
Ron E
Je pense que la réponse de @ jiliagre est probablement celle que je voudrais utiliser aujourd'hui. Sur le poisson %selfpeut être utilisé à la place de$$
Steven D
8

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 
jlliagre
la source
6

Remarque à propos de certaines implémentations plus légères (téléphones Android, busybox, etc.): psne prend pas toujours en charge le -pcommutateur, mais vous pouvez effectuer la recherche avec une commande telle que ps | grep "^$$ ". (Cette grepexpression rationnelle identifiera de manière unique le PID, ainsi il n’y aura pas de faux positifs.)

palswim
la source
7
ps | grep $$peut toujours donner de faux positifs si, par exemple, votre processus actuel est 1234et qu'il existe un processus 12345.
Keith Thompson
4

Il y a deux manières très simples:

  • Utilisation de la commande ps :

    ps -o comm= $$

    ou

    ps -h -o comm -p $$

    où:

    • -hou en terminant toutes les options avec =pour ne montrer aucun en-tête.
    • -o commpour afficher uniquement le processus nom de base ( bashau lieu de /bin/bash).
    • -p <PID> liste seulement les processus dont la liste de formulaires PID est fournie.
  • Utilisation du pseudo système de fichiers d'informations de processus / proc :

    cat /proc/$$/comm

    Cette option se comporte exactement comme la pscommande ci-dessus.

    ou

    readlink /proc/$$/exe

    Cela /proc/PID/exerenvoie au fichier en cours d’exécution, qui dans ce cas ferait référence à / 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, un code source ou un terminal, en tant que liens vers le fichier binaire de l’interpréteur de shell utilisé.

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

L’utilisation de /procest vraiment utile via le /proc/selflien qui relie au PID de la commande en cours.

David Goitia
la source
3

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

ps -p$$ -o cmd="",comm="",fname="" 2>/dev/null | sed 's/^-//' | grep -oE '\w+' | head -n1
Sébastien
la source
cela me donne mon nom de répertoire actuel; aussi, sous cshet tcshça me donneAmbiguous output redirect.
iconoclast
2

Si vous l'avez enregistré dans vos variables d'environnement, vous pouvez utiliser les éléments suivants:

echo $SHELL
jasonleonhard
la source
Cela renverra très probablement le chemin de l'exécutable shell de votre shell de connexion. Il n’est pas certain que le shell de connexion soit celui que vous utilisez actuellement.
Kusalananda
1

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

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

Utiliser des backticks pour faire fonctionner jsh (Heirlomm Shell).

Dans beaucoup de coquilles, le test direct des ps -o args= -p $$œuvres, mais busybox ashéchoue sur cela (résolu).

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

Les derniers ;:servent à garder le shell en marche pour ksh et zsh.

Des tests sur plusieurs systèmes vous seront utiles. Veuillez commenter si cela ne fonctionne pas pour vous.

Ne fonctionne pas dans le cshtype d'obus.


la source
Sur OS / X, dans mes tests, je reçois au moins 3 lignes, une pour le shell, une pour /usr/lib/dyld, une pour /private/var/db/dyld/dyld_shared_cache_x86_64.
Stéphane Chazelas
Oui, il ne sélectionne plus que les entrées dans / bin et / usr / bin
Stéphane Chazelas le
@ StéphaneChazelas Peut-être que c'est mieux maintenant?
0

Je mets $MYSHELLde 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 tcshsection est probablement imprudente dans un script de style POSIX car elle est radicalement différente (d'où l'avertissement et une pause de cinq secondes). (D'une part, les cshcoquilles de style ne peuvent pas faire 2>/dev/nullou >&2, comme indiqué dans le fameux discours de Csh Programming Considered Harmful .)

Adam Katz
la source
-1

Vous pouvez simplement utiliser la echo $0commande pour vérifier quel shell vous utilisez et <name_of_the_shell> --versionpour vérifier la version du shell. (par exemple. bash --version)

Sachin C
la source
Steven D en a déjà parlé
:)