我有一个关于如何判断用户正在使用哪个shell的问题。假设一个脚本,如果用户正在使用zsh,那么将PATH放到他的.zshrc
中,如果使用bash应该放入.bashrc。并相应地设置rvmrc。
#!/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
答案 0 :(得分:96)
如果shell是Zsh,则定义变量$ZSH_VERSION
。同样适用于Bash和$BASH_VERSION
。
if [ -n "$ZSH_VERSION" ]; then
# assume Zsh
elif [ -n "$BASH_VERSION" ]; then
# assume Bash
else
# asume something else
fi
但是,这些变量只能告诉您使用哪个shell来运行上面的代码。所以你必须在用户的shell中source
这个片段。
作为替代方案,您可以使用$SHELL
环境变量(应包含用户首选shell的绝对路径)并根据该变量的值猜测shell:
case $SHELL in
*/zsh)
# assume Zsh
;;
*/bash)
# assume Bash
;;
*)
# assume something else
esac
当/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
无论使用哪个shell来运行脚本,都可以从脚本运行最后一个建议。
答案 1 :(得分:38)
做echo $0
它显示-zsh
如果它是 zsh 而-bash
如果它是 bash
编辑:有时会返回-zsh
,有时会返回zsh
,而bash也是如此,idk为什么。
答案 2 :(得分:27)
警告:你似乎问过的问题,你想问的问题,以及你应该问的问题是三个不同的事情。
“用户正在使用哪个shell”不明确。您的尝试看起来像是在尝试确定哪个shell正在执行您的脚本。除了你的意思是你的用户要编辑那个脚本之外,你总是将它放在脚本的#!
行中,所以这对你没用。
我认为,您想要问的是用户最喜欢的外壳是什么。这不能完全可靠地确定,但您可以涵盖大多数情况。检查SHELL
环境变量。如果它包含fish
,zsh
,bash
,ksh
或tcsh
,则用户最喜欢的shell可能就是那个shell。但是,这是您的问题的错误问题。
.bashrc
,.zshrc
,.cshrc
等文件是shell初始化文件。它们不是定义环境变量的正确位置。在那里定义的环境变量只能在用户启动该shell的终端中使用,而不能在从GUI启动的程序中使用。该定义还将覆盖用户在子句中可能进行的任何自定义。
定义环境变量的正确位置在会话启动文件中。这与用户选择shell无关。不幸的是,没有一个地方可以定义环境变量。在很多系统上,~/.profile
都可以使用,但这不是通用的。请参阅https://unix.stackexchange.com/questions/4621/correctly-setting-environment以及我链接到那里的其他帖子,以便进行更长时间的讨论。
答案 3 :(得分:6)
您可以尝试
echo $SHELL
答案 4 :(得分:2)
替代方案可能不适用于所有炮弹。
for x in $(ps -p $$)
do
ans=$x
done
echo $ans
答案 5 :(得分:1)
根据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
答案 6 :(得分:0)
我自己也遇到了类似的问题,因此决定:
_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
答案 7 :(得分:0)
其他答案以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
答案 8 :(得分:0)
/
不再导出名为 zsh
的环境变量。您可以通过这种方式区分 bash 和 $ZSH_VERSION
:
zsh
if [ -n "$ZSH" ]; then
echo 'zsh';
elif [ -n "$BASH_VERSION" ]; then
echo 'bash';
else
echo "Could not identify shell"
fi
follows 这种内部方法。