我正在寻找一种简单可靠的方法来从脚本或源文件(而不是从命令行)中获取当前 shell 的名称。我本来希望这样做,$(basename "$SHELL")但是如果我的登录 shell 是zsh并且我在 some_script.sh 中有以下代码
this_shell=$( basename "$SHELL" )
echo "The Shell is $this_shell"
echo "The Shell is $0"
Run Code Online (Sandbox Code Playgroud)
我用 运行它bash some_script.sh,它仍然列出zsh而不是bash即使使用的解释器是/bin/bash. 我不确定为什么外壳设计者选择显示默认外壳而不是当前外壳,但这似乎是我们所坚持的。
还有一些其他稍微相似的问题(这里和这里),但他们的答案在很多方面都不够。
echo $0. 如上面的脚本所示,这失败了。(是的,它可以在交互式 shell 命令行中使用,但是您为什么不知道您使用的是什么 shell?) ps -p $$,但缺乏跨平台、跨外壳兼容的 sed/awk 命令来通过管道传递它以获取外壳名称并忽略随之而来的其他信息为骑行。$BASH_VERSION和$ZSH_VERSION。我想支持尽可能多的 shell,例如fish, csh, tcsh.如何可靠和准确地检测出任何 当前的壳呢?我正在寻找可以跨平台、在脚本中以及尽可能多且合理的 shell 中工作的东西1。
更新:当我发布这个问题时,我希望 shell 中内置了一些工具来为我们提供这些信息,但事实并非如此。由于现在似乎不可避免地依赖于shell之外的东西,我应该更明确地表明我要求一个跨平台的解决方案(虽然我对上述其他答案的反对暗示了这一点,但如果你不这样做,可能很容易错过'不仔细阅读问题)。
更新 2 如果有人仍然认为这是 Linux-only 问题的重复,因为 Stéphane 的回答不是 Linux-only,这里是我要求的和他提供的之间的区别。(请注意,他写的东西很巧妙,我不是在敲它,但它并没有解决我的问题。)
.zshrc或.bash_profile分支或其他)。如果你想看到的东西,将工作,看看ShellDetective GitHub上。这可能更容易看出 SE 上已经存在的内容与这个问题正在寻找的内容之间的差异(实际上是为了满足这个问题的需求而编写的,这些需求在其他任何地方都没有得到满足)。
(PS,如果你不相信有这样的用例,想象一下这些函数被引入.zshrc, .bash_profile,或者.profile取决于正在使用的服务器和它有哪些可用的外壳。它们是来源所以他们没有shebang线。他们如果它们可以在任何 shell 中工作,则最有用,但有时他们必须知道它们在哪个 shell 中才能知道如何表现。)
小智 6
我用这种组合取得了很好的结果:
ps -p $$ | awk '$1 != "PID" {print $(NF)}'
Run Code Online (Sandbox Code Playgroud)
在 Tru64 (OSF/1) 上,输出在外壳周围有括号。钉在tr -d '()'删除它们。
ps -p $$ | awk '$1 != "PID" {print $(NF)}' | tr -d '()'
Run Code Online (Sandbox Code Playgroud)
似乎适用于所有 shell,在 Solaris 10 和 RHEL 5.7 / 6.4 上。没有测试其他发行版,例如 Debian、Ubuntu 或 Mint,但我认为它们应该都可以正常工作;我也不知道 FreeBSD 是否可以工作。
gwi*_*lie -2
使用以下风险自负的免责声明
tmp=`head -n 1 $0`
SHELL_BIN=`readlink -f ${tmp#*!}`
SHELL=${SHELL_BIN##*/}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6012 次 |
| 最近记录: |