如何确定我正在使用的当前shell ?
仅仅ps命令的输出就足够了吗?
如何在不同风格的Unix中实现这一点?
如何确定我正在使用的当前shell ?
仅仅ps命令的输出就足够了吗?
如何在不同风格的Unix中实现这一点?
当前回答
如果您只是想检查您正在运行(特定版本的)Bash,最好的方法是使用$BASH_VERSINFO数组变量。作为一个(只读)数组变量,它不能在环境中设置, 因此,您可以确定它来自当前shell(如果有的话)。
但是,由于Bash在作为sh调用时具有不同的行为,因此还需要检查以/ Bash结尾的$ Bash环境变量。
在我写的一个脚本中,使用了带-(不是下划线)的函数名,并依赖于关联数组(在Bash 4中添加),我有以下完整性检查(有有用的用户错误消息):
case `eval 'echo $BASH@${BASH_VERSINFO[0]}' 2>/dev/null` in
*/bash@[456789])
# Claims bash version 4+, check for func-names and associative arrays
if ! eval "declare -A _ARRAY && func-name() { :; }" 2>/dev/null; then
echo >&2 "bash $BASH_VERSION is not supported (not really bash?)"
exit 1
fi
;;
*/bash@[123])
echo >&2 "bash $BASH_VERSION is not supported (version 4+ required)"
exit 1
;;
*)
echo >&2 "This script requires BASH (version 4+) - not regular sh"
echo >&2 "Re-run as \"bash $CMD\" for proper operation"
exit 1
;;
esac
在第一种情况下,您可以忽略对特性的功能检查,只假设将来的Bash版本是兼容的。
其他回答
你可以试试:
ps | grep `echo $$` | awk '{ print $4 }'
Or:
echo $SHELL
Try
ps -p $$ -oargs=
or
ps -p $$ -ocomm=
我的解决方案:
ps -o command | grep -v -e "\<ps\>" -e grep -e tail | tail -1
这应该可以跨不同的平台和shell进行移植。它像其他解决方案一样使用ps,但它不依赖于sed或awk,并过滤掉管道和ps本身的垃圾,因此shell应该始终是最后一个条目。这样我们就不需要依赖不可移植的PID变量或选择正确的行和列。
我已经在Debian和macOS上用Bash、Z shell (zsh)和fish进行了测试(如果不专门为fish更改表达式,大多数解决方案都无法使用,因为它使用了不同的PID变量)。
没有一个答案适用于fish shell(它没有变量$$或$0)。
这适用于我(测试在sh, bash, fish, ksh, csh, true, tcsh,和zsh;openSUSE 13.2):
ps | tail -n 4 | sed -E '2,$d;s/.* (.*)/\1/'
该命令输出类似bash的字符串。这里我只使用ps、tail和sed(没有GNU扩展;尝试添加——posix来检查它)。它们都是标准的POSIX命令。我相信尾巴是可以去掉的,但是我的sed fu还不够强。
在我看来,这个解决方案不是很可移植,因为它不能在OS x上工作:(
我尝试过许多不同的方法,对我来说最好的方法是:
ps -p $$
它也可以在Cygwin下工作,并且不能像PID grepping那样产生假阳性。经过一些清理,它只输出一个可执行名称(在Cygwin With path下):
ps -p $$ | tail -1 | awk '{print $NF}'
你可以创建一个函数,这样你就不必记住它:
# Print currently active shell
shell () {
ps -p $$ | tail -1 | awk '{print $NF}'
}
…然后执行shell。
它在Debian和Cygwin下进行了测试。