2012-03-28 4 views
34

У меня вопрос о том, как определить, какую оболочку пользователь использует. Предположим, что скрипт, если пользователь использует zsh, затем помещает PATH в свой .zshrc, и если использование bash должно быть помещено в .bashrc. И установите rvmrc соответственно.Как определить, использует ли zsh или bash

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

Я попытался следующие, но это не работает: (

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

несколько цитат не имеют себе равных. – kev

+0

Не было бы смысла вкладывать это в '.profile', который переносится через оболочки, включая' sh'? – tripleee

+0

@tripleee Привет, потому что это определенная вещь для bash или zsh, я думаю ... – juanitofatas

ответ

23

Слово предупреждения: вопрос, который вы, кажется, задали, вопрос, который вы хотели задать, и вопрос, который вы должны задать, - это три разные вещи.

«Какая оболочка пользователь использует» является неоднозначной. Ваша попытка выглядит так, будто вы пытаетесь определить, какая оболочка выполняет ваш скрипт. Это всегда будет то, что вы помещаете в строку сценария #!, если только вы не хотите, чтобы ваши пользователи редактировали этот сценарий, так что это вам не полезно.

Что вы хотели спросить, я думаю, это то, что является любимой оболочкой пользователя. Это невозможно определить полностью надежно, но вы можете охватить большинство случаев. Проверьте переменную среды SHELL. Если он содержит fish, zsh, bash, ksh или tcsh, любимая оболочка пользователя, вероятно, является оболочкой. Однако это неправильный вопрос для вашей проблемы.

Файлы типа .bashrc, .zshrc, .cshrc и т. Д. Являются файлами инициализации оболочки. Они не подходят для определения переменных среды. Определенная там переменная среды будет доступна только в терминале, где пользователь запускает эту оболочку, а не в программах, запускаемых из графического интерфейса. Это определение также отменяет любую настройку, которую пользователь мог сделать в подсекции.

Правильное место для определения переменной окружения находится в файле запуска сеанса. Это в основном не связано с выбором пользователем оболочки. К сожалению, нет единого места для определения переменных окружения. На многих системах ~/.profile будет работать, но это не универсально. См. https://unix.stackexchange.com/questions/4621/correctly-setting-environment и другие сообщения, на которые я ссылаюсь, для более продолжительного обсуждения.

+3

«Это всегда будет то, что вы помещаете в строку #!». Это неверно, так как пользователь может легко передать имя файла сценария в качестве параметра в любую оболочку. –

+1

@MichaelMior: И пользователь, вероятно, * будет * передавать имя файла сценария в качестве параметра в какую-либо случайную оболочку, если скрипт не отмечен как исполняемый. В зависимости от вашего процесса установки это может быть или не быть. – Kevin

66

Если оболочка ЗШ, переменная $ZSH_VERSION определяется Аналогично для Bash и $BASH_VERSION

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

Однако эти переменные указывают только, какая оболочка используется для запуска вышеуказанного кода. Таким образом, вам нужно будет source этот фрагмент в пользовательском оболочка.

В качестве альтернативы можно использовать переменную $SHELL среды (которая должна содержать абсолютный путь к предпочтительной оболочки пользователя) и угадать оболочку из значения этой переменной:

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

Конечно выше воли fail, когда /bin/sh является символической ссылкой на /bin/bash.

Если вы хотите, чтобы полагаться на $SHELL, безопаснее на самом деле выполнить код:

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 

Это последнее предложение может быть запущен из скрипта независимо от оболочки используется для запуска сценария.

+0

Привет Спасибо за ваш ответ. Я пробовал ваш последний метод. Пока я живу в zsh, я запускал ваш скрипт, но он все еще говорит, что я использую bash. Я сделал снимок: [screenshot] (https://skitch.com/kaluvchris/8p7ua/terminal-zsh-79x24-1) – juanitofatas

+0

@juanitofatas. Вы запустили скрипт под bash, так что он правильно сообщил, что он работает под bash. – Gilles

+0

@ Gilles На скриншоте показано, что я бежал zsh ???? – juanitofatas

2

Альтернатива, может не работать для всех оболочек.

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

'ps -p $$ --no-headers -o cmd' немного лучше. – forivall

+0

За исключением тех случаев, когда это не работает: 'ps: unknown option - no-headers' – Jools

0

Myself, имеющие аналогичные проблемы, довольствовалась:

_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

Только эхо $ 0 это говорит -zsh, если это ЗШ и -bash если это Баш

EDIT: Иногда она возвращается -zsh и иногда zsh и то же самое с bash, idk why.

+0

Это не работает для всех оболочек, но по-прежнему мой метод go-to в любое время, когда я сажусь в CLI - это работает больше раз, чем нет. Оболочки, такие как Fish, ничего не вернут для 'echo $ 0' – kmatheny

+0

.' -zsh' или '-bash' используется для обозначения оболочки входа. Если у него нет '-' infront имени, тогда пользователь использует не-login-оболочку – smac89

+0

. Это не работает, если вы находитесь в функции, где $ 0 вернет имя функции. – Jools

Смежные вопросы