775 votes

Comment déterminer le shell interactif actuel dans lequel je me trouve ? (ligne de commande)

Comment puis-je déterminer la coquille actuelle sur laquelle je travaille ?

Est-ce que la sortie du ps le commandement seul est suffisant ?

Comment cela peut-il être fait dans différentes versions d'Unix ?

9 votes

Test de capacités particulières (par exemple, est-ce qu'il fait ! substitution ?) est probablement plus portable que de trouver le nom du shell. Les habitudes locales peuvent vous faire exécuter quelque chose nommé /bin/sh qui pourrait en fait être ash, dash, bash, etc.

2 votes

@msw : Cela semble être un bon commentaire sauf qu'il me laisse me demander "comment ?".

0 votes

Il semble qu'il n'y ait pas de réponse simple à cette question. Si nous ne pouvons pas requête le shell, peut-être que la meilleure approche est de toujours spécifier la coquille. Je ne suis pas sûr que cela soit toujours possible, mais peut-être est-ce plus facile à réaliser que ce que l'on pense généralement.

935voto

DVK Points 63282
  • Il existe trois approches pour trouver le nom de l'exécutable du shell actuel :

    Veuillez noter que ces trois approches peuvent être trompées si l'exécutable du shell est /bin/sh mais il s'agit en fait d'un nouveau nom bash par exemple (ce qui arrive fréquemment).

    Ainsi, votre deuxième question, à savoir si ps La réponse à cette question est " pas toujours ".

    1. echo $0 - imprimera le nom du programme... qui dans le cas du shell est le shell actuel.

    2. ps -ef | grep $$ | grep -v grep - cela recherchera l'ID du processus actuel dans la liste des processus en cours. Comme le processus actuel est le shell, il sera inclus.

      Ce n'est pas fiable à 100%, comme vous pouvez l'avoir autre les processus dont ps comprend le même numéro que l'ID du processus de l'interpréteur de commandes, surtout si cet ID est un petit nombre (par exemple, si le PID de l'interpréteur de commandes est "5", vous pouvez trouver des processus appelés "java5" ou "perl5" dans la même liste de processus). grep sortie !). C'est le deuxième problème avec l'approche "ps", en plus de l'impossibilité de se fier au nom du shell.

    3. echo $SHELL - Le chemin d'accès au shell actuel est stocké dans le champ SHELL pour n'importe quel shell. La mise en garde est que si vous lancez un shell explicitement en tant que sous-processus (par exemple, ce n'est pas votre shell de connexion), vous obtiendrez la valeur de votre shell de connexion à la place. Si cela est possible, utilisez l'option ps o $0 approche.


  • Si, toutefois, l'exécutable ne correspond pas à votre shell actuel (par ex. /bin/sh est en fait bash ou ksh), vous avez besoin d'une heuristique. Voici quelques variables environnementales spécifiques aux différents shells :

    • $version est défini sur tcsh

    • $BASH est défini sur bash

    • $shell (minuscule) est défini comme le nom réel du shell dans csh ou tcsh.

    • $ZSH_NAME est défini sur zsh

    • ksh a $PS3 y $PS4 alors que le shell Bourne normal ( sh ) n'a que $PS1 y $PS2 set. Cela semble généralement être le plus difficile à distinguer - la uniquement différence dans l'ensemble des variables d'environnement entre sh y ksh que nous avons installé sur Solaris boxen est $ERRNO , $FCEDIT , $LINENO , $PPID , $PS3 , $PS4 , $RANDOM , $SECONDS et $TMOUT .

0 votes

${.sh.version} est défini sur ksh93

23 votes

ps -p $$ como Matthew Slattery fait remarquer. Pour ksh : echo $KSH_VERSION o echo ${.sh.version} .

0 votes

@Dennish - mon ksh n'a pas encore défini KSH_VERSION. et echo ${.sh.version} renvoie "Bad Substitution". Voir ma solution ci-dessus

126voto

Matthew Slattery Points 21628

ps -p $$

devrait fonctionner partout où les solutions impliquant ps -ef y grep faire (sur toute variante d'Unix qui supporte Options POSIX pour ps ) et ne souffrira pas des faux positifs introduits par la recherche d'une séquence de chiffres qui peut apparaître ailleurs.

16 votes

Certains shells ont leur propre version intégrée de ps qui peuvent ne pas comprendre -p vous devrez donc utiliser /bin/ps -p $$ .

16 votes

Toutes les coquilles avec lesquelles je suis familier comprennent $$ sauf pour fish avec lequel vous devriez utiliser ps -p %self .

3 votes

En fait, vous ne devriez pas vous fier à des chemins difficiles tels que /bin/ps . ps pourrait facilement (en fait, c'est tout à fait normal de nos jours) être installé en /usr/bin . $(which ps) -p $$ est un meilleur moyen. Bien sûr, cela ne fonctionnera pas pour les poissons, et peut-être pour d'autres coquillages. Je pense que c'est (which ps) -p %self dans le poisson.

54voto

Nahuel Fouilleul Points 3018

Essayez

ps -p $$ -oargs=

o

ps -p $$ -ocomm=

6 votes

C'est une belle et courte histoire. J'ai utilisé moi-même ps -o fname --no-headers $$ .

0 votes

Merci. J'ai trouvé que c'était la meilleure option à utiliser dans un script pour garder les commandes spécifiques à bash. test `ps -p $$ -ocomm=` == "bash" && do_something_that_only_works_in_bash . (La ligne suivante dans mon script a l'équivalent pour csh).

2 votes

J'ai constaté que si vous faites cela à partir d'un sous-shell, cela peut conduire à des lignes supplémentaires fallacieuses en faisant correspondre le PID du parent ainsi que le processus shell réel. Pour cela, j'utilise -q au lieu de -p : SHELL=$(ps -ocomm= -q $$)

24voto

karlphillip Points 46502

Vous pouvez essayer :

ps | grep `echo $$` | awk '{ print $4 }'

Ou :

echo $SHELL

7 votes

Quel est l'intérêt de grep suivi de awk, lorsque /pattern/ { action } fera ?

0 votes

# dans l'alias zshell shell='echo ${SHELL:t}''

9 votes

$SHELL contient un shell, qui est configuré par défaut pour l'utilisateur actuel. Elle ne reflète pas l'interpréteur de commandes en cours d'exécution. Aussi, il est préférable d'utiliser ps -p $$ que le grepping $$ à cause des faux positifs.

12voto

ennuikiller Points 28005

ps est la méthode la plus fiable. Il n'est pas garanti que la variable d'environnement SHELL soit activée et même si elle l'est, elle peut être facilement falsifiée.

16 votes

+1 $SHELL est le shell par défaut pour les programmes qui doivent en générer un. Il ne reflète pas nécessairement le shell en cours d'exécution.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X