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

Jua*_*tas 49 bash zsh sh

我有一个关于如何分辨用户使用的shell的问题.假设一个脚本,如果用户正在使用zsh,那么将PATH放到他的.zshrc,如果使用bash应该放入.bashrc.并相应地设置rvmrc.

#!/usr/bin/env bash
export PATH='/usr/local/bin:$PATH'" >> ~/.zshrc
source ~/.zshrc
Run Code Online (Sandbox Code Playgroud)

我尝试过以下但不起作用:(

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
Run Code Online (Sandbox Code Playgroud)

adl*_*adl 113

如果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
Run Code Online (Sandbox Code Playgroud)

但是,这些变量只能告诉您使用哪个shell来运行上面的代码.所以你必须source在用户的shell中使用这个片段.

作为替代方案,您可以使用$SHELL环境变量(应包含用户首选shell的绝对路径)并根据该变量的值猜测shell:

case $SHELL in
*/zsh) 
   # assume Zsh
   ;;
*/bash)
   # assume Bash
   ;;
*)
   # assume something else
esac
Run Code Online (Sandbox Code Playgroud)

当然,当/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
Run Code Online (Sandbox Code Playgroud)

无论使用哪个shell来运行脚本,都可以从脚本运行最后一个建议.

  • @juanitofatas你在终端上运行了zsh.从那个交互式zsh,你运行bash来解释一个脚本.在该脚本中,您测试了哪个shell执行了脚本,答案是bash. (3认同)

the*_*chd 43

只需回显$ 0,如果它是zsh则表示-zsh,如果是bash则表示-bash

编辑:有时它返回echo $0,有时-zsh和bash一样,idk为什么.

  • `-zsh`或`-bash`用于表示登录shell.如果它没有名称前面的`-`,那么用户正在使用非登录shell (3认同)
  • 如果您使用的是函数,则该函数将无效,其中$ 0将返回函数名称。 (3认同)
  • 这并不适用于所有 shell,但仍然是我每次坐在 CLI 前的首选方法——它工作的次数比不工作的次数要多。诸如 Fish 之类的 Shell 不会为 `echo $0` 返回任何东西 (2认同)

Gil*_*il' 28

一句警告:你似乎问的问题,你想问的问题,以及你应该问的问题是三个不同的事情.

"用户正在使用哪个shell"是不明确的.您的尝试看起来像是在尝试确定哪个shell正在执行您的脚本.#!除非你的意思是你的用户要编辑那个脚本,否则这总是会出现在脚本行中的任何内容,所以这对你没用.

我想,你想要问的是用户最喜欢的外壳是什么.这不能完全可靠地确定,但您可以涵盖大多数情况.检查SHELL环境变量.如果它包含fish,zsh,bash,ksh或者tcsh,用户最喜欢的外壳是可能是壳.但是,这是您的问题的错误问题.

文件,如.bashrc,.zshrc,.cshrc等等都是shell初始化文件.它们不是定义环境变量的正确位置.在那里定义的环境变量只能在用户启动该shell的终端中使用,而不能在从GUI启动的程序中使用.该定义还将覆盖用户在子过程中可能进行的任何定制.

定义环境变量的正确位置在会话启动文件中.这与用户选择shell无关.不幸的是,没有一个地方可以定义环境变量.在很多系统上,~/.profile都可以工作,但这不是普遍的.请参阅https://unix.stackexchange.com/questions/4621/correctly-setting-environment以及我链接到那里的其他帖子以进行更长时间的讨论.

  • "这总是会出现在脚本的#!行中的任何内容" - 这不是真的,因为用户可以轻松地将脚本文件名作为参数传递给任何shell. (9认同)
  • @MichaelMior:如果脚本没有标记为可执行文件,用户可能会*将脚本文件名作为参数传递给某个随机shell.根据您的安装过程,这可能是也可能不是. (2认同)
  • 不出所料,接受的解决方案仅提供修辞性的训诫和惩罚,而不是有意义的解决方案。每个人都想要[adl](/sf/users/1948481/)的[权威答案](/sf/answers/693775771/),它提供了几个通用片段解决实际问题。 (2认同)

Vid*_*rom 8

你可以简单地尝试

 echo $SHELL
Run Code Online (Sandbox Code Playgroud)


tim*_*our 5

其他答案失败了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
Run Code Online (Sandbox Code Playgroud)

  • 如果我从 zsh 打开 bash 子 shell,则会成功,这与 `echo $SHELL` 不同 (2认同)