如何确定我正在使用的当前shell ?
仅仅ps命令的输出就足够了吗?
如何在不同风格的Unix中实现这一点?
如何确定我正在使用的当前shell ?
仅仅ps命令的输出就足够了吗?
如何在不同风格的Unix中实现这一点?
当前回答
没有一个答案适用于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上工作:(
其他回答
echo $$ # Gives the Parent Process ID
ps -ef | grep $$ | awk '{print $8}' # Use the PID to see what the process is.
你如何知道你当前的shell是什么?
Ps是最可靠的方法。SHELL环境变量不能保证被设置,即使设置了,也很容易被欺骗。
如果您只是想检查您正在运行(特定版本的)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版本是兼容的。
下面将始终给出实际使用的shell -它获得实际可执行文件的名称,而不是shell名称(即ksh93而不是ksh,等等)。对于/bin/sh,它将显示实际使用的shell,即破折号。
ls -l /proc/$$/exe | sed 's%.*/%%'
我知道有很多人说ls输出永远不应该被处理,但是您所使用的shell以特殊字符命名,或者位于以特殊字符命名的目录中的可能性有多大?如果情况仍然如此,还有很多其他不同的做法。
正如托比·斯佩特(Toby Speight)所指出的,这将是实现相同目标的更适当、更干净的方式:
basename $(readlink /proc/$$/exe)
你可以使用echo $SHELL|sed "s/\/bin\// g"