1

我汇总了以下内容来检测 Bash 是否正在运行脚本:

################################################################################
# Checks whether execution is going through Bash, aborting if it isn't. TinoSino

current_shell="$(
  ps                  `# Report a snapshot of the current processes` \
      -p $$           `# select by PID` \
      -o comm         `# output column: Executable namename` \
  |\
  paste               `# Merge lines of files ` \
      -s              `# paste one file at a time instead of in parallel` \
      -               `# into standard output` \
  |\
  awk                 `# Pick from list of tokens` \
      '{ print $NF }' `# print only last field of the command output`
)"

current_shell="${current_shell#-}" # Remove starting '-' character if present

if [ ! "${current_shell}" = 'bash' ]; then

  echo "This script is meant to be executed by the Bash shell but it isn't."
  echo 'Continuing from another shell may lead to unpredictable results.'
  echo 'Execution will be aborted... now.'

  return 0

fi

unset current_shell
################################################################################

我不是专门要求你对它进行代码审查,因为你会把我送到 CodeReview;我的问题是:

  • 你将如何测试这个放在我脚本顶部的“执行警卫”是否确实可靠完成了它的工作?

我正在考虑安装虚拟机并在每台机器上安装诸如zsh,csh等之类的东西。但这对我来说看起来太耗时了。更好的方法来做到这一点?

如果你发现一个直接的错误,请向我指出。我认为,只是挥舞着腿等待被压扁的刺眼虫子应该被压扁。

4

2 回答 2

6

这最好写成

if [ -z "$BASH_VERSION" ]
then
   echo "Please run me in bash"
   exit 1
fi

至于测试,从 /etc/shells 获取非 bash shell 的列表,然后运行脚本,其中每个都验证您是否收到错误消息。

于 2013-03-15T23:38:11.357 回答
2

如果对“保证”正确结果并不重要,我只会建议您自己滚动。我认为这样的保证是不可能的,但大多数时候你最多只针对几个 shell,只关心现代版本。很少有人应该关心版本检测。在 POSIX 之外编写可移植代码需要知道自己在做什么。

不要为了中止而费心检测外壳。如果人们想通过忽略shebang来向自己开枪,那是他们的问题。

于 2013-03-16T02:07:46.697 回答