如何让 shell 使用 zsh 或 bash 进行自我检测

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9910966/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 21:52:40  来源:igfitidea点击:

How to get shell to self-detect using zsh or bash

bashzshsh

提问by Juanito Fatas

I've a question on how to tell which shell the user is using. Suppose a script that if the user is using zsh, then put PATH to his .zshrcand if using bash should put in .bashrc. And set rvmrc accordingly.

我有一个关于如何判断用户正在使用哪个 shell 的问题。假设一个脚本,如果用户正在使用 zsh,则将 PATH 放入他的.zshrc,如果使用 bash 则应放入 .bashrc。并相应地设置 rvmrc。

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

I've tried the following but it does not work : (

我已经尝试了以下但它不起作用:(

if [[ 
if [ -n "$ZSH_VERSION" ]; then
   # assume Zsh
elif [ -n "$BASH_VERSION" ]; then
   # assume Bash
else
   # assume something else
fi
== "bash" ]]; then export PATH='/usr/local/bin:$PATH' >> ~/.bashrc elif [[
case $SHELL in
*/zsh) 
   # assume Zsh
   ;;
*/bash)
   # assume Bash
   ;;
*)
   # assume something else
esac
== "zsh" ]]; then export PATH='/usr/local/bin:$PATH' >> ~/.zshrc fi # ... more commands ... if [[
if [ -n "`$SHELL -c 'echo $ZSH_VERSION'`" ]; then
   # assume Zsh
elif [ -n "`$SHELL -c 'echo $BASH_VERSION'`" ]; then
   # assume Bash
else
   # assume something else
fi
== "bash" ]]; then [[ -s '/Users/`whoami`/.rvm/scripts/rvm' ]] && source '/Users/`whoami`/.rvm/scripts/rvm' >> ~/.bashrc source ~/.bashrc elif [[
for x in $(ps -p $$)
do
  ans=$x
done
echo $ans
== "zsh" ]]; then [[ -s '/Users/`whoami`/.rvm/scripts/rvm' ]] && source '/Users/`whoami`/.rvm/scripts/rvm' >> ~/.zshrc source ~/.zshrc fi

采纳答案by Gilles 'SO- stop being evil'

A word of warning: the question you seem to have asked, the question you meant to ask, and the question you should have asked are three different things.

一句话警告:你似乎问的问题,你打算问的问题,以及你应该问的问题是三个不同的问题。

“Which shell the user is using” is ambiguous. Your attempt looks like you're trying to determine which shell is executing your script. That's always going to be whatever you put in the #!line of the script, unless you meant your users to edit that script, so this isn't useful to you.

“用户正在使用哪个 shell”是不明确的。您的尝试看起来像是在尝试确定哪个 shell 正在执行您的脚本。这始终是您在#!脚本行中放置的任何内容,除非您的意思是您的用户编辑该脚本,因此这对您没有用。

What you meant to ask, I think, is what the user's favorite shell is. This can't be determined fully reliably, but you can cover most cases. Check the SHELLenvironment variable. If it contains fish, zsh, bash, kshor tcsh, the user's favorite shell is probably that shell. However, this is the wrong question for your problem.

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

Files like .bashrc, .zshrc, .cshrcand so on are shell initialization files. They are not the right place to define environment variables. An environment variable defined there would only be available in a terminal where the user launched that shell and not in programs started from a GUI. The definition would also override any customization the user may have done in a subsession.

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

The right place to define an environment variable is in a session startup file. This is mostly unrelated to the user's choice of shell. Unfortunately, there's no single place to define environment variables. On a lot of systems, ~/.profilewill work, but this is not universal. See https://unix.stackexchange.com/questions/4621/correctly-setting-environmentand the other posts I link to there for a longer discussion.

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

回答by adl

If the shell is Zsh, the variable $ZSH_VERSIONis defined. Likewise for Bash and $BASH_VERSION.

如果 shell 是 Zsh,$ZSH_VERSION则定义了该变量。对于 Bash 和$BASH_VERSION.

_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                                                                                                                                               

However, these variables only tell you which shell is being used to run the above code. So you would have to sourcethis fragment in the user's shell.

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

As an alternative, you could use the $SHELLenvironment variable (which should contain absolute path to the user's preferred shell) and guess the shell from the value of that variable:

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

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

Of course the above will fail when /bin/shis a symlink to /bin/bash.

当然,当/bin/sh是到/bin/bash.

If you want to rely on $SHELL, it is safer to actually execute some code:

如果要依赖$SHELL,实际执行一些代码会更安全:

 echo $SHELL

This last suggestion can be run from a script regardless of which shell is used to run the script.

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

回答by 2xsaiko

Just do echo $0it says -zshif it's zshand -bashif it's bash

只要做echo $0它说-zsh,如果它的zsh中-bash,如果它的庆典

EDIT: Sometimes it returns -zshand sometimes zshand the same with bash, idk why.

编辑:有时它会返回-zsh,有时zsh与 bash 相同,我知道为什么。

回答by pizza

An alternative, might not work for all shells.

另一种选择可能不适用于所有外壳。

##代码##

回答by agathodaimon

Myself having a similar problem, settled for:

我自己也有类似的问题,解决了:

##代码##

回答by djangofan

Here is how I am doing it based on a previous answer from Gilles :

以下是我根据 Gilles 之前的回答来做的:

##代码##

回答by Vidor Vistrom

You can simply try

你可以简单地尝试

##代码##