Comment déterminer le shell actuel sur lequel je travaille?

Comment puis-je déterminer le shell actuel sur lequel je travaille?

est-ce que la seule sortie de la commande ps serait suffisante?

comment cela peut-il être fait dans différentes saveurs D'UNIX?

493
demandé sur Mat 2010-07-25 01:35:28
la source

23 ответов

  • il y a 3 approches pour trouver le nom de l'exécutable du shell actuel:

    veuillez noter que les 3 approches peuvent être dupées si l'exécutable du shell est /bin/sh mais il s'agit en fait d'un renommé bash , par exemple (ce qui arrive fréquemment).

    ainsi votre deuxième question de savoir si ps sortie fera Est répondu par " pas toujours ".

    1. echo "151930920" - imprimera le nom du programme... qui, dans le cas de shell est la coque réelle

    2. ps -ef | grep $$ | grep -v grep - ceci recherchera l'identifiant de processus courant dans la liste des processus en cours d'exécution. Puisque le processus actuel est shell, il sera inclus.

      ce n'est pas 100% fiable, comme vous pourriez avoir d'autres processus dont La liste ps inclut le même numéro que l'identifiant de processus de shell, surtout si cet identifiant est un petit # (par exemple si l'identifiant de processus de shell est" 5", vous pouvez trouver des processus appelés" java5 "ou" perl5 "dans la même sortie grep !). C'est le deuxième problème avec les "ps" approche, en plus de ne pas pouvoir compter sur la coquille nom.

    3. echo $SHELL - le chemin vers le shell courant est stocké comme la variable SHELL pour toute Shell. La mise en garde pour celle-ci est que si vous lancez explicitement un shell 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 c'est une possibilité, utilisez l'approche ps ou "1519100920" .


  • si, cependant, l'exécutable ne correspond pas à votre shell (par exemple /bin/sh est en fait bash ou ksh), vous avez besoin d'heuristiques. Voici quelques variables environnementales spécifiques aux divers types de coquillages:

    • $version est réglé sur tcsh

    • $BASH est placé sur bash

    • $shell (lowercase) est défini à nom de shell réel dans csh ou tcsh

    • $ZSH_NAME est réglé sur zsh

    • ksh a $PS3 et $PS4 mis, tandis que Normal Bourne shell ( sh ) a seulement $PS1 et $PS2 mis. Cela semble généralement le plus difficile à distinguer - la seule différence dans l'ensemble des variables environnementales entre sh et ksh que nous avons installé sur Solaris boxen est $ERRNO , $FCEDIT , $LINENO , $PPID , $PS3 , $PS4 , $RANDOM , $SECONDS , $TMOUT .

636
répondu DVK 2017-07-24 19:51:17
la source

ps -p $$

devrait fonctionner n'importe où que les solutions impliquant ps -ef et grep (sur N'importe quelle variante D'Unix qui supporte les options positives pour ps ) et ne souffriront pas des faux positifs introduits par le grêlage pour une séquence de chiffres qui peuvent apparaître ailleurs.

77
répondu Matthew Slattery 2010-07-25 02:09:37
la source

Essayer

ps -p $$ -oargs=

ou

ps -p $$ -ocomm=
32
répondu Nahuel Fouilleul 2012-07-15 16:53:12
la source

, Vous pouvez essayer:

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

ou:

echo $SHELL
20
répondu karlphillip 2010-07-25 01:38:44
la source

si vous voulez simplement vous assurer que l'utilisateur invoque script avec bash:

if [ ! -n "$BASH" ] ;then echo Please run this script "151900920" with bash; exit 1; fi
20
répondu Peter Lamberg 2016-09-18 07:31:40
la source

$SHELL n'a pas besoin de toujours afficher le shell actuel. Il ne reflète que le shell par défaut à invoquer.

pour tester ce qui précède, dire bash est le shell par défaut, essayer echo $SHELL , puis dans le même terminal ,entrer dans un autre shell(ksh par exemple) et essayer $SHELL , vous verrez le résultat comme bash dans les deux cas.

pour obtenir le nom du shell courant, Utilisez cat /proc/$$/cmdline et le chemin vers l'exécutable shell par readlink /proc/$$/exe

10
répondu Sibi Rajasekaran 2012-10-15 16:03:20
la source

ps est la méthode la plus fiable. Le SHELL envar n'est pas garanti pour être réglé et même si c'est le cas, il peut être facilement mystifié

9
répondu ennuikiller 2010-07-25 01:39:39
la source

j'ai un truc simple pour trouver le shell courant. Il suffit de taper une chaîne de caractères aléatoire (qui n'est pas une commande). Il échouera et retournera une erreur "non trouvé", mais au début de la ligne il dira quel shell il est:

ksh: aaaaa: not found [No such file or directory]
bash: aaaaa: command not found
8
répondu user5659949 2015-12-09 19:19:27
la source

Cela donnera toujours le shell utilisé - obtient le nom de l'exécutable réel et non le nom du shell (i.e. ksh93 au lieu de ksh etc.) Pour /bin/sh indiquera le shell utilisé: i.e. dash

ls -l /proc/$$/exe | sed 's%.*/%%'

je sais que voici beaucoup qui disent ls sortie devrait être plus récent traité, mais quelle est la probabilité que vous aurez un shell que vous utilisez nommé avec des caractères spéciaux ou placé dans un répertoire nommé avec des caractères spéciaux personnages? Si c'est encore le cas, voici beaucoup d'autres exemples le faisant différemment.

7
répondu vadimbog 2016-02-14 12:25:22
la source

Ma variante sur l'impression du processus parent.

ps -p $$ | awk ' == PP {print }' PP=$$

pourquoi lancer des applications inutiles, alors que "awk" peut le faire pour vous?

4
répondu Matthew Stier 2015-08-25 16:37:28
la source

à condition que votre /bin/sh supporte la norme POSIX et que votre système ait la commande lsof installée - une alternative possible à lsof pourrait dans ce cas être pid2path - vous pouvez également utiliser (ou adapter) le script suivant qui imprime des chemins complets:

#!/bin/sh
# cat /usr/local/bin/cursh
set -eu
pid="$$"

set -- sh bash zsh ksh ash dash csh tcsh pdksh mksh fish psh rc scsh bournesh wish Wish login

unset echo env sed ps lsof awk getconf

# getconf _POSIX_VERSION  # reliable test for availability of POSIX system?
PATH="`PATH=/usr/bin:/bin:/usr/sbin:/sbin getconf PATH`"
[ $? -ne 0 ] && { echo "'getconf PATH' failed"; exit 1; }
export PATH

cmd="lsof"
env -i PATH="${PATH}" type "$cmd" 1>/dev/null 2>&1 || { echo "$cmd not found"; exit 1; }

awkstr="`echo "[email protected]" | sed 's/\([^ ]\{1,\}\)/|\//g; s/ /$/g' | sed 's/^|//; s/$/$/'`"

ppid="`env -i PATH="${PATH}" ps -p $pid -o ppid=`"
[ "${ppid}"X = ""X ] && { echo "no ppid found"; exit 1; }

lsofstr="`lsof -p $ppid`" || 
   { printf "%s\n" "lsof failed" "try: sudo lsof -p \`ps -p $$ -o ppid=\`"; exit 1; }

printf "%s\n" "${lsofstr}" | 
   LC_ALL=C awk -v var="${awkstr}" '$NF ~ var {print $NF}'
3
répondu carlo 2013-03-20 21:30:04
la source

j'ai essayé plusieurs approches différentes et la meilleure pour moi est:

ps -p $$

il fonctionne également sous Cygwin et ne peut pas produire de faux positifs comme le grepping PID. Avec un certain nettoyage, il affiche juste un nom exécutable (sous Cygwin avec le chemin):

ps -p $$ | tail -1 | awk '{print $NF}'

vous pouvez créer une fonction pour ne pas avoir à la mémoriser:

# print currently active shell
shell () {
  ps -p $$ | tail -1 | awk '{print $NF}'
}

...et ensuite il suffit d'exécuter shell .

testé sous Debian et Cygwin.

3
répondu Dawid Ferenczy 2014-10-14 15:57:50
la source
echo $$ # Gives the Parent Process ID 
ps -ef | grep $$ | awk '{print }' #use the PID to see what the process is.

de http://www.unix.com/unix-dummies-questions-answers/10390-how-do-you-know-what-your-current-shell.html

2
répondu Moisei 2010-07-25 01:41:25
la source

sous Mac OS X (&FreeBSD):

ps -p $$ -axco command | sed -n '$p' 
1
répondu zaga 2010-07-25 22:02:39
la source

si vous voulez juste vérifier que vous utilisez (une version particulière de) Bash, la meilleure façon de le faire est d'utiliser la variable $BASH_VERSINFO . En tant que variable (readonly) array, elle ne peut pas être définie dans l'environnement, vous pouvez donc être sûr qu'il vient (si tant est qu'il vient) du shell courant. Cependant, depuis Bash a un comportement différent lorsqu'il est invoqué comme sh , vous devez également vérifier que la variable d'environnement $BASH se termine par /bash .

dans un script J'ai écrit que utilise des noms de fonction avec - (pas de soulignement) et dépend des réseaux associatifs (ajouté en Bash 4), J'ai le contrôle de santé suivant (avec le message d'erreur utile de l'utilisateur):

case `eval 'echo [email protected]${BASH_VERSINFO[0]}' 2>/dev/null` in
    */[email protected][456789])
        # Claims bash version 4+, check for func-names and associative arrays
        if ! eval "declare -A _ARRAY && func-name() { :; }" 2>/dev/null; then
            echo >&2 "bash $BASH_VERSION is not supported (not really bash?)"
            exit 1
        fi
        ;;
    */[email protected][123])
        echo >&2 "bash $BASH_VERSION is not supported (version 4+ required)"
        exit 1
        ;;
    *)
        echo >&2 "This script requires BASH (version 4+) - not regular sh"
        echo >&2 "Re-run as \"bash $CMD\" for proper operation"
        exit 1
        ;;
esac

vous pourriez omettre la vérification fonctionnelle un peu paranoïaque des caractéristiques dans le premier cas, et supposons que les futures versions de bash soient compatibles.

1
répondu Alex Dupuy 2014-08-11 22:00:26
la source

Grepping PID à partir de la sortie de "ps" n'est pas nécessaire parce que vous pouvez lire la ligne de commande respective pour n'importe quel PID à partir de la structure de répertoire /proc:

echo $(cat /proc/$$/cmdline)

cependant, cela pourrait ne pas être mieux que simplement:

echo "151910920"

à propos de l'exécution de shell réellement différent que le nom indique, une idée est de demander la version de shell en utilisant le nom que vous avez obtenu précédemment:

<some_shell> --version

semble échouer avec exit code 2 tandis que d'autres donnent quelque chose d'utile (mais je ne suis pas en mesure de tout vérifier car je ne les ai pas):

$ sh --version
sh: 0: Illegal option --
echo $?
2
1
répondu ajaaskel 2014-10-30 21:16:40
la source

aucune réponse ne fonctionnait avec fish shell (il n'y a pas de variables $$ ou "151930920" ).

cela fonctionne pour moi (testé sur sh , bash , fish , ksh , csh , true , tcsh , et zsh ; openSUSE 13.2):

ps | tail -n 4 | sed -E '2,$d;s/.* (.*)//'

cette commande affiche une chaîne de caractères comme bash . J'utilise ici seulement ps , tail , et sed (sans GNU extesions; essayez d'ajouter --posix pour vérifier). Ce sont tous des commandes POSIX standard. Je suis sûr que tail peut être enlevé, mais mon sed fu n'est pas assez fort pour le faire.

il me semble que cette solution n'est pas très portable car elle ne fonctionne pas sur OS X.: (

1
répondu rominf 2014-12-11 16:17:58
la source

ce n'est pas une solution très propre, mais fait ce que vous voulez.

je me rends compte que la réponse est un peu tardive dans cette bonne vieille 2015, mais...

#MUST BE SOURCED..
getshell() {
    local shell="`ps -p $$ | tail -1 | awk '{print }'`"

    shells_array=(
    # It is important that the shells are listed by the decrease of their length name.
        pdksh
        bash dash mksh
        zsh ksh
        sh
    )

    local suited=false
    for i in ${shells_array[*]}; do
        if ! [ -z `printf $shell | grep $i` ] && ! $suited; then
            shell=$i
            suited=true
        fi
    done

    echo $shell
}
getshell

Maintenant vous pouvez utiliser $(getshell) --version.

cela ne fonctionne, cependant, que sur les coquilles de type ksh.

1
répondu theoden 2015-07-09 22:08:50
la source

ma solution:

ps -o command | grep -v -e "\<ps\>" -e grep -e tail | tail -1

ce système doit être portable sur différentes plates-formes et coquilles. Il utilise ps comme d'autres solutions, mais il ne s'appuie pas sur sed ou awk et filtre les rebuts de la tuyauterie et ps lui-même de sorte que la coque devrait toujours être la dernière entrée. De cette façon, nous n'avons pas besoin de nous appuyer sur des variables PID Non portatives ou de choisir les lignes et les colonnes appropriées.

j'ai testé sur Debian et MacOS avec bash, zsh, et fish (qui ne fonctionne pas avec la plupart de ces solutions sans changer l'expression spécifiquement pour les poissons, parce qu'il utilise une variable PID différente).

1
répondu wickles 2017-05-18 02:52:28
la source

il y a plusieurs façons de découvrir le shell et sa version correspondante. En voici quelques - uns qui ont fonctionné pour moi.

droit devant

  1. $> echo 0 $ (vous donne le nom du programme. Dans mon cas, la sortie était - bash )
  2. $ > $SHELL (ceci vous amène dans le shell et dans l'invite vous obtenez le shell nom et version. Dans mon cas bash3.2$ )
  3. $ > echo $SHELL (cela vous donnera le chemin de l'exécutable. Dans mon cas / bin /bash )
  4. $ > $SHELL --version (ceci donnera des informations complètes sur le logiciel shell avec le type de licence)

Hackish approche

$> ******* (Tapez un ensemble de caractères aléatoires et dans la sortie vous obtiendrez le nom du shell. Dans mon cas, -bash: chapitre 2-un-exemple-isomorphe a ' l'application: commande introuvable )

1
répondu Devang Paliwal 2017-09-19 10:30:27
la source

veuillez utiliser la commande suivante:

 # ps -p $$ | tail -1 | awk '{print }'
0
répondu Ranjithkumar T 2014-10-28 09:10:09
la source

faites ce qui suit pour savoir si votre Shell utilise DASH/BASH.

1) ls-la / bin /sh , si le résultat est /bin/sh ->/bin/bash ==> alors votre shell utilise BASH.

si le résultat est /bin/sh ->/bin/dash = = > alors votre shell utilise DASH.

si vous voulez passer de BASH à DASH ou vice-versa, utilisez le code ci-dessous ln - s /bin/bash /bin/sh (changement de shell BASH)

NOTE: Si la commande ci-dessus aboutit à une erreur disant que /bin/sh existe déjà, supprimez /bin/sh et réessayez.

0
répondu Shiva 2017-12-14 11:22:48
la source

celui-ci fonctionne bien sur RHEL, MacOS, BSD et quelques AIXes

ps -T $$ | awk 'NR==2{print $NF}' 

alternativement, suivre un devrait aussi fonctionner si pstree est disponible,

pstree | egrep $$ | awk 'NR==2{print $NF}'
-1
répondu martin zahrubsky 2017-12-13 13:16:07
la source

Autres questions sur bash shell unix csh tcsh