2012-03-28 6 views
34

Ich habe eine Frage, wie Sie sagen, welche Shell der Benutzer verwendet. Angenommen ein Skript, das, wenn der Benutzer zsh verwendet, dann setzen Sie PATH auf .zshrc und wenn Sie bash verwenden sollten in .bashrc einfügen. Und setze rvmrc entsprechend.Wie kann ich sagen, ob es zsh oder bash verwendet?

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

Ich habe das versucht, folgende, 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 
+1

mehrere Zitate sind unübertroffen. – kev

+0

Wäre es nicht sinnvoller, dies in '.profile' zu ​​schreiben, das über Shells hinweg portierbar ist, einschließlich' sh'? – tripleee

+0

@tripleee Hallo, weil es eine spezielle Sache für Bash oder Zsh ist, denke ich ... – juanitofatas

Antwort

23

Ein Wort der Warnung: die Frage, die Sie scheinbar gestellt haben, die Frage, die Sie stellen wollten, und die Frage, die Sie stellen sollten, sind drei verschiedene Dinge.

"Welche Shell der Benutzer verwendet" ist mehrdeutig. Ihr Versuch sieht so aus, als würden Sie herausfinden, welche Shell Ihr Skript ausführt. Das wird immer das sein, was Sie in die Zeile #! des Skripts schreiben, es sei denn, Sie haben gemeint, dass Ihre Benutzer dieses Skript bearbeiten, also ist das für Sie nicht nützlich.

Was Sie fragen wollten, denke ich, ist, was die Lieblingsschale des Benutzers ist. Dies kann nicht vollständig zuverlässig festgestellt werden, aber Sie können die meisten Fälle abdecken. Überprüfen Sie die Umgebungsvariable . 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 und so weiter 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, in dem der Benutzer diese Shell gestartet hat, und nicht in Programmen, die von einer GUI gestartet wurden. Die Definition würde auch jede Anpassung überschreiben, die der Benutzer möglicherweise in einer Unterabsprache vorgenommen hat.

Der richtige Ort zum Definieren einer Umgebungsvariablen befindet sich in einer Sitzungsstartdatei. Dies hängt meistens nicht mit der Auswahl der Shell durch den Benutzer zusammen. Leider gibt es keinen einzigen Ort, um Umgebungsvariablen zu definieren. Auf vielen Systemen wird ~/.profile funktionieren, aber das ist nicht universell. Siehe https://unix.stackexchange.com/questions/4621/correctly-setting-environment und die anderen Beiträge, die ich verlinke, für eine längere Diskussion.

+3

"Das wird immer sein, was auch immer Sie in die #! Zeile des Skripts schreiben" - Das ist nicht wahr, da ein Benutzer einfach den Skriptdateinamen als Parameter an irgendeine Shell übergeben könnte. –

+1

@MichaelMior: Und der Benutzer * wird * den Skriptdateinamen als Parameter an eine zufällige Shell übergeben, wenn das Skript nicht als ausführbar markiert ist. Abhängig von Ihrem Installationsprozess kann dies der Fall sein oder auch nicht. – Kevin

66

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 Ihnen jedoch nur, welche Shell zum Ausführen des obigen Codes verwendet wird.So müssten Sie dieses Fragment im Benutzer source haben Schale.

Als Alternative könnten Sie die $SHELL Umgebungsvariable verwenden (die bevorzugte Shell enthalten sollte absoluten Pfad des Benutzers) und erraten, die Schale aus dem Wert dieser Variablen:

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

Natürlich ist die oben Willen fehlgeschlagen, wenn /bin/sh ein Symlink zu /bin/bash ist.

Wenn Sie auf $SHELL verlassen wollen, ist es sicherer, tatsächlich einige Code ausfü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 ausgeführt werden, unabhängig davon, welche Shell verwendet wird, um das Skript auszuführen.

+0

Hallo Danke für deine Antwort. Ich habe deine letzte Methode ausprobiert. Während ich in zsh wohnt, habe ich dein Skript ausgeführt, aber es heißt immer noch, dass ich bash benutze. Ich habe ein Foto gemacht: [screenshot] (https://skitch.com/kaluvchris/8p7ua/terminal-zsh-79x24-1) – juanitofatas

+0

@juanitofatas Sie haben das Skript unter bash ausgeführt, also hat es korrekt berichtet, dass es unter bash lief. – Gilles

+0

@Gilles In dem Screenshot zeigt es, dass ich zsh ???? – juanitofatas

2

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

for x in $(ps -p $$) 
do 
    ans=$x 
done 
echo $ans 
+1

'ps -p $$ --no-headers -o cmd' ist ein bisschen besser. – forivall

+0

Außer wenn es nicht funktioniert: 'ps: unknown option - no-headers' – Jools

0

Myself ein ähnliches Problem hat, entschied sich 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                                    
19

Just do $ 0 echo sagt es -ZSH wenn es zsh ist und -bash wenn es bash ist

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

+0

Dies funktioniert nicht für alle Shells, ist aber immer noch meine Go-to-Methode, wenn ich mich an einen CLI-it setze arbeitet öfter als nicht. Shells wie Fish geben für »echo $ 0« nichts zurück. – kmatheny

+0

Die »-zsh« oder »-bash« werden verwendet, um eine Login-Shell anzugeben. Wenn es nicht den '-' vor dem Namen hat, verwendet der Benutzer eine Nicht-Login-Shell – smac89

+0

Dies funktioniert nicht, wenn Sie in einer Funktion sind, wobei $ 0 den Funktionsnamen zurückgibt. – Jools

Verwandte Themen