如何判断它是否使用zsh或bash

时间:2012-03-28 15:37:09

标签: bash zsh sh

我有一个关于如何判断用户正在使用哪个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

9 个答案:

答案 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环境变量。如果它包含fishzshbashkshtcsh,则用户最喜欢的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 这种内部方法。