如今,您通常可以在系统上找到POSIX shell,因此通常意味着您可以使用POSIX语言编写脚本(对符合性错误进行模运算)。
唯一的问题是/bin/sh
有时不是POSIX shell。而且,您必须将该#!
行硬编码为脚本,以使其表现为出色的可执行文件。您不能只要求用户研究问题,然后以调用您的脚本/path/to/posix/shell myscript
。
因此,诀窍是在脚本中使用POSIX功能,但要使脚本自动找到POSIX shell。一种方法是这样的:
#!/bin/sh
# At this point, we may be running under some old shell
# we have to tread carefully.
# note how we use test rather than [ ] syntax and avoid
# depending on test with no argument producing a failure;
# i.e. "test $posix_shell".
if ! test x$posix_shell = x ; then
# the three possible shell paths are just an example;
# please extend as necessary.
for shell in /usr/xpg4/bin/sh /bin/bash /usr/bin/bash ; do
if test -x $shell ; then
posix_shell=$shell
fi
done
if test x$posix_shell = x ; then
echo "no POSIX shell found"
exit 1
# or we could avoid bailing here and just fall back on /bin/sh:
# echo "falling back on /bin/sh: cross your fingers that it works"
# posix_shell=/bin/sh
fi
export posix_shell
# plain "$@" is broken in ancient shells!
# I seem to recall ${@+"$@"}: not sure if that's the right trick.
exec $posix_shell $0 ${@+"$@"} # can we count on exec in legacy shells?
fi
# phew, at this point in the script we have been re-executed and are
# being interpreted by some reasonably modern shell. We can use $(...)
# command substitution, and other features.
还有其他方法,例如代码生成。用一个小的脚本来增强脚本,该脚本需要一个不含#的脚本文件!行,并添加一个。
您可能做的最坏的事情就是开始编写整个脚本,使其在1981年的Bourne shell上运行。只有在您必须为实际上没有任何其他shell的系统编写脚本时,才有必要。