2012-03-28 11 views
34

Ho una domanda su come dire quale shell l'utente sta usando. Supponiamo uno script che se l'utente sta usando zsh, allora metti PATH al suo .zshrc e se si usa bash dovrebbe mettere in .bashrc. E imposta rvmrc di conseguenza.come dire se sta usando zsh o bash

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

Ho provato quanto segue ma non funziona: (

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

diverse virgolette sono ineguagliate. – kev

+0

Non avrebbe più senso inserirlo in '.profile', che è trasportabile attraverso shells, incluso' sh'? – tripleee

+0

@ triple Ciao, perché è una cosa specifica per bash o zsh, penso ... – juanitofatas

risposta

23

Una parola di avvertimento: la domanda che sembri aver chiesto, la domanda che intendevi porre e la domanda che dovresti aver posto sono tre cose diverse.

"La shell che l'utente sta utilizzando" è ambigua. Sembra che tu stia cercando di determinare quale shell sta eseguendo il tuo script. Questo sarà sempre quello che inserirai nella riga #! dello script, a meno che non intendi che gli utenti lo modificino, quindi questo non ti è utile.

Quello che intendevi chiedere, penso, è la shell preferita dell'utente. Questo non può essere determinato in modo completamente affidabile, ma puoi coprire la maggior parte dei casi. Controlla la variabile di ambiente SHELL. Se contiene fish, zsh, bash, ksh o tcsh, la shell preferita dell'utente è probabilmente quella shell. Tuttavia, questa è la domanda sbagliata per il tuo problema.

File come .bashrc, .zshrc, .cshrc e così via sono file di inizializzazione della shell. Non sono il posto giusto per definire le variabili d'ambiente. Una variabile d'ambiente definita sarebbe disponibile solo in un terminale in cui l'utente ha lanciato quella shell e non nei programmi avviati da una GUI. La definizione supererebbe anche qualsiasi personalizzazione che l'utente avrebbe potuto fare in una sottosessione.

Il posto giusto per definire una variabile di ambiente si trova in un file di avvio della sessione. Questo è in gran parte non correlato alla scelta della shell dell'utente. Sfortunatamente, non esiste un unico posto per definire le variabili d'ambiente. Su molti sistemi, ~/.profile funzionerà, ma questo non è universale. Vedi https://unix.stackexchange.com/questions/4621/correctly-setting-environment e gli altri post che rimando a lì per una discussione più lunga.

+3

"Sarà sempre ciò che inserirai nella riga #! Dello script" - Non è vero, dal momento che un utente può facilmente passare il nome file dello script come parametro a qualsiasi shell. –

+1

@MichaelMior: E l'utente probabilmente * passerà il nome file dello script come parametro a qualche shell casuale, se lo script non è contrassegnato come eseguibile. A seconda del processo di installazione, questo potrebbe o meno essere il caso. – Kevin

66

Se il guscio è Zsh, la variabile $ZSH_VERSION è definito Analogamente per Bash e $BASH_VERSION

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

Tuttavia, queste variabili indicano solo quale shell viene utilizzata per eseguire il codice precedente. Quindi, si dovrebbe inserire source nel frammento conchiglia.

In alternativa, è possibile utilizzare la variabile $SHELL ambiente (che dovrebbe contenere percorso assoluto al guscio preferito dell'utente) e intuire il guscio dal valore di tale variabile:

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

Naturalmente quanto sopra volontà fallire quando /bin/sh è un collegamento simbolico a /bin/bash.

Se si vuole fare affidamento su $SHELL, è più sicuro per eseguire in realtà un po 'di codice:

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 

Questo ultimo suggerimento può essere eseguito da uno script di shell, indipendentemente da quale viene utilizzato per eseguire lo script.

+0

Ciao Grazie per la risposta. Ho provato il tuo ultimo metodo. Mentre risiedo in zsh, ho eseguito il tuo script, ma continua a dire che sto usando bash. Ho scattato una foto: [screenshot] (https://skitch.com/kaluvchris/8p7ua/terminal-zsh-79x24-1) – juanitofatas

+0

@juanitofatas Hai eseguito lo script in bash, quindi ha segnalato correttamente che era in esecuzione sotto bash. – Gilles

+0

@Gilles Nello screenshot mostra che ho eseguito zsh ???? – juanitofatas

2

Un'alternativa potrebbe non funzionare per tutte le shell.

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

'ps -p $$ --no-headers -o cmd' è un po 'meglio. – forivall

+0

Tranne quando non funziona: 'ps: opzione sconosciuta - no-headers' – Jools

0

Io avendo un problema simile, si stabilirono per:

_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

Basta echo $ 0 dice -zsh se è zsh e -bash se è bash

EDIT: A volte ritorna -zsh e talvolta zsh e lo stesso con bash, idk perché.

+0

Questo non funziona per tutte le shell, ma è sempre il mio metodo go-to ogni volta che mi siedo su una CLI - it Funziona più volte. Conchiglie come Fish non restituiscono nulla per 'echo $ 0' – kmatheny

+0

' -zsh' o '-bash' è usato per indicare una shell di login. Se non ha il prefisso '-' del nome, l'utente sta utilizzando una shell non di login – smac89

+0

Questo non funziona se sei in una funzione, dove $ 0 restituirà il nome della funzione. – Jools