77 votes

Comment faire en sorte que le shell s'auto-détecte en utilisant zsh ou bash ?

J'ai une question sur la façon de savoir quel shell l'utilisateur utilise. Supposons qu'un script qui si l'utilisateur utilise zsh, alors mette PATH à son .zshrc et si vous utilisez bash, mettez-le dans .bashrc. Et définir rvmrc en conséquence.

#!/usr/bin/env bash
export PATH='/usr/local/bin:$PATH' >> ~/.zshrc
source ~/.zshrc

J'ai essayé ce qui suit mais cela ne fonctionne pas : (

if [[ $0 == "bash" ]]; then
  export PATH='/usr/local/bin:$PATH' >> ~/.bashrc
elif [[ $0 == "zsh" ]]; then
  export PATH='/usr/local/bin:$PATH' >> ~/.zshrc
fi

# ... more commands ...

if [[ $0 == "bash" ]]; then
  [[ -s '/Users/`whoami`/.rvm/scripts/rvm' ]] && source '/Users/`whoami`/.rvm/scripts/rvm' >> ~/.bashrc
  source ~/.bashrc
elif [[ $0 == "zsh" ]]; then
  [[ -s '/Users/`whoami`/.rvm/scripts/rvm' ]] && source '/Users/`whoami`/.rvm/scripts/rvm' >> ~/.zshrc
  source ~/.zshrc
fi

0 votes

Ne serait-il pas plus judicieux de mettre cela dans .profile qui est portable sur tous les shells, y compris sh ?

0 votes

@tripleee Salut, car c'est une chose spécifique pour bash ou zsh je pense....

1 votes

173voto

adl Points 7294

Si le shell est Zsh, la variable $ZSH_VERSION est définie. De même pour Bash et $BASH_VERSION .

if [ -n "$ZSH_VERSION" ]; then
   # assume Zsh
elif [ -n "$BASH_VERSION" ]; then
   # assume Bash
else
   # assume something else
fi

Cependant, ces variables vous indiquent seulement quel shell est utilisé pour exécuter le code ci-dessus. Vous devez donc source ce fragment dans le shell de l'utilisateur.

Comme alternative, vous pouvez utiliser l'option $SHELL (qui doit contenir le chemin absolu vers le shell préféré de l'utilisateur) et devine le shell à partir de la valeur de cette variable :

case $SHELL in
*/zsh) 
   # assume Zsh
   ;;
*/bash)
   # assume Bash
   ;;
*)
   # assume something else
esac

Bien sûr, ce qui précède échouera si /bin/sh est un lien symbolique vers /bin/bash .

Si vous voulez compter sur $SHELL il est plus sûr d'exécuter réellement du code :

if [ -n "`$SHELL -c 'echo $ZSH_VERSION'`" ]; then
   # assume Zsh
elif [ -n "`$SHELL -c 'echo $BASH_VERSION'`" ]; then
   # assume Bash
else
   # assume something else
fi

Cette dernière suggestion peut être exécutée à partir d'un script indépendamment du shell utilisé pour exécuter le script.

55voto

user205138 Points 1

Fais-le. echo $0 il dit -zsh si c'est zsh et -bash si c'est bash

EDIT : Parfois, il retourne -zsh et parfois zsh et la même chose avec Bash, je ne sais pas pourquoi.

2 votes

Cela ne fonctionne pas pour tous les shells, mais c'est toujours ma méthode de prédilection chaque fois que je m'assois devant une CLI - elle fonctionne la plupart du temps. Les shells tels que Fish ne retourneront rien pour echo $0

5 votes

En -zsh o -bash est utilisé pour indiquer un shell de connexion. S'il n'a pas l'attribut - devant le nom, alors l'utilisateur utilise un shell non connecté.

5 votes

Cela ne fonctionne pas si vous êtes dans une fonction, où $0 retournera le nom de la fonction.

38voto

Gilles Points 37537

Un mot d'avertissement : la question que vous semblez avoir posée, la question que vous vouliez poser et la question que vous auriez dû poser sont trois choses différentes.

"Quel shell l'utilisateur utilise" est ambigu. Votre tentative semble vouloir déterminer quel shell exécute votre script. Cela va toujours être ce que vous mettez dans la balise #! de la ligne script, à moins que vous ayez voulu que vos utilisateurs modifient ce script, donc cela ne vous est pas utile.

Ce que vous vouliez demander, je pense, c'est quel est le shell préféré de l'utilisateur. Cela ne peut pas être déterminé de manière totalement fiable, mais vous pouvez couvrir la plupart des cas. Vérifiez le SHELL variable d'environnement. Si elle contient fish , zsh , bash , ksh o tcsh le shell préféré de l'utilisateur est probablement ce shell. Cependant, ce n'est pas la bonne question pour votre problème.

Des fichiers comme .bashrc , .zshrc , .cshrc et ainsi de suite sont des fichiers d'initialisation du shell. Ils ne sont pas le bon endroit pour définir des variables d'environnement. Une variable d'environnement définie à cet endroit ne serait disponible que dans un terminal où l'utilisateur a lancé cet interpréteur de commandes et non dans des programmes lancés depuis une interface graphique. La définition remplacerait également toute personnalisation effectuée par l'utilisateur dans une sous-session.

Le bon endroit pour définir une variable d'environnement est dans un fichier de démarrage de session. Ceci n'est pas lié au choix de l'interpréteur de commandes par l'utilisateur. Malheureusement, il n'existe pas d'endroit unique pour définir les variables d'environnement. Sur beaucoup de systèmes, ~/.profile fonctionnera, mais ce n'est pas universel. Voir https://unix.stackexchange.com/questions/4621/correctly-setting-environment et les autres messages que je cite pour une discussion plus approfondie.

7voto

Vidor Vistrom Points 1288

Vous pouvez simplement essayer

 echo $SHELL

1 votes

C'est raté. Dans Zsh, si j'ouvre un sous-shell bash et que je fais cela, il est toujours indiqué que /bin/zsh ce qui n'est évidemment pas la coquille.

4voto

timotheecour Points 525

Les autres réponses échouent avec set -u

  if [ ! -z ${ZSH_VERSION+x} ]; then
    echo "this is zsh"
    echo ${(%):-%x}
  elif [ ! -z ${BASH_VERSION+x} ]; then
    echo "this is bash"
    echo $BASH_SOURCE
  else
    echo "not recognized"
  fi

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