web-dev-qa-db-de.com

wie man erkennt, ob es zsh oder bash verwendet

Ich habe eine Frage, wie Sie feststellen können, welche Shell der Benutzer verwendet. Angenommen, ein Skript setzt, wenn der Benutzer zsh verwendet, PATH in seinen .zshrc und wenn bash verwendet wird, muss .bashrc eingefügt werden. Und rvmrc entsprechend einstellen.

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

Ich habe folgendes versucht, aber es funktioniert nicht: (

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
44
Juanito Fatas

Ein Wort der Warnung: Die Frage, die Sie scheinbar gestellt haben, die Frage, die Sie stellen wollten, und die Frage, die Sie hätten stellen sollen, sind drei verschiedene Dinge.

"Welche Shell der Benutzer verwendet" ist mehrdeutig. Ihr Versuch scheint zu versuchen, festzustellen, welche Shell Ihr Skript ausführt. Das ist immer das, was Sie in die #!-Zeile des Skripts schreiben, es sei denn, Sie wollten, dass Ihre Benutzer das Skript bearbeiten, und das ist für Sie nicht nützlich.

Ich denke, Sie wollten fragen, was die Lieblings-Shell des Benutzers ist. Dies kann nicht völlig zuverlässig ermittelt werden, aber Sie können die meisten Fälle abdecken. Überprüfen Sie die Umgebungsvariable Shell. Wenn es fish, zsh, bash, ksh oder tcsh enthält, ist die bevorzugte Shell des Benutzers wahrscheinlich diese Shell. Dies ist jedoch die falsche Frage für Ihr Problem.

Dateien wie .bashrc, .zshrc, .cshrc usw. sind Shell-Initialisierungsdateien. Sie sind nicht der richtige Ort, um Umgebungsvariablen zu definieren. Eine dort definierte Umgebungsvariable wäre nur in einem Terminal verfügbar, an dem der Benutzer diese Shell gestartet hat, und nicht in Programmen, die über eine GUI gestartet wurden. Die Definition würde auch alle Anpassungen überschreiben, die der Benutzer möglicherweise in einer Subsession vorgenommen hat.

Der richtige Ort zum Definieren einer Umgebungsvariablen befindet sich in einer Sitzungsstartdatei. Dies hat meistens nichts mit der Auswahl der Shell durch den Benutzer zu tun. Leider gibt es keine einzige Stelle, um Umgebungsvariablen zu definieren. Auf vielen Systemen wird ~/.profile funktionieren, dies ist jedoch nicht universell. Siehe https://unix.stackexchange.com/questions/4621/correctly-setting-environment und die anderen Posts, auf die ich dort für eine längere Diskussion verlinkt bin.

25
Gilles

Wenn die Shell Zsh ist, wird die Variable $ZSH_VERSION definiert. Ebenso für Bash und $BASH_VERSION.

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

Diese Variablen sagen jedoch nur, welche Shell zum Ausführen des obigen Codes verwendet wird. Sie müssten also dieses Fragment in der Benutzer-Shell source setzen.

Alternativ können Sie die Umgebungsvariable $Shell verwenden (die den absoluten Pfad zur bevorzugten Shell des Benutzers enthalten sollte) und die Shell anhand des Werts dieser Variablen erraten:

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

Das obige wird natürlich fehlschlagen, wenn /bin/sh ein symbolischer Link zu /bin/bash ist.

Wenn Sie sich auf $Shell verlassen wollen, ist es sicherer, tatsächlich Code auszuführen:

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

Dieser letzte Vorschlag kann von einem Skript aus ausgeführt werden, unabhängig davon, mit welcher Shell das Skript ausgeführt wird.

90
adl

Geben Sie einfach $ 0 .__ ein. Es sagt -zsh, wenn es sich um zsh handelt, und -bash, wenn es bash ist

EDIT: Manchmal gibt es -zsh und manchmal zsh und das gleiche mit bash zurück, idk warum.

35

Eine Alternative funktioniert möglicherweise nicht für alle Schalen.

for x in $(ps -p $$)
do
  ans=$x
done
echo $ans
2
pizza

Hier ist, wie ich es mache, basierend auf einer vorherigen Antwort von Gilles:

if [ -n "$ZSH_VERSION" ]; then
  Shell_PROFILE="$HOME/.zprofile"
else
  Shell_PROFILE="$HOME/.bash_profile"
fi
echo "export VAR1=whatever" >> $Shell_PROFILE
echo "INFO: Refreshing your Shell profile: $Shell_PROFILE"
if [ -n "$ZSH_VERSION" ]; then
  exec zsh --login
else
  source $Shell_PROFILE
fi
1
djangofan

Ich hatte ein ähnliches Problem, entschied mich für:

_Shell="$(ps -p $$ --no-headers -o comm=)"                                                                                                       
if [[ $_Shell == "zsh" ]]; then                                                                                                                  
    read -q -s "?Do it?: "                                                                                                                    
fi                                                                                                                                               
Elif [[ $_Shell == "bash" || $_Shell == "sh" ]]; then                                                                                              
    read -n 1 -s -p "Do it [y/n] "                                                                                                            
fi                                                                                                                                               
0
agathodaimon