当我在 shell 中研究this question的答案时,我注意到,即使/bin/sh指向系统上的/bin/bash,这两个命令的行为也不同。首先,输出

ls -lh /bin/sh

是:
lrwxrwxrwx 1 root root 4 Apr 22  2013 /bin/sh -> bash*

但是,通过/bin/sh调用以下命令:
/bin/sh -c "script.sh 2> >( grep -v FILTER 2>&1 )"

返回此错误:
/bin/sh: -c: line 0: syntax error near unexpected token '>'
/bin/sh: -c: line 0: 'script.sh 2> >( grep -v FILTER 2>&1 )'

通过/bin/bash运行相同命令时:
/bin/bash -c "script.sh 2> >( grep -v FILTER 2>&1 )"

成功执行,以下是输出:
This should be on stderr

供引用,这是script.sh的内容:
#!/bin/sh
echo "FILTER: This should be filtered out" 1>&2
echo "This should be on stderr" 1>&2
echo "FILTER: This should be filtered out" 1>&2

为什么两个调用的行为不同?

最佳答案

bash查看$argv[0]的值(bash在C语言中实现),以确定如何调用它。

当作为sh调用时,其行为记录在in the manual中:



bash处于POSIX模式下时,有一长串(当前有46项)会发生变化的事物documented here

(POSIX模式可能最有用,它是测试脚本是否可移植到非bash shell的一种方法。)

顺便说一句,根据调用它们的名称改变其行为的程序是相当普遍的。某些版本的grepfgrepegrep被实现为单个可执行文件(尽管GNU grep并未执行此操作)。 view通常是vivim的符号链接(symbolic link);以view调用它会导致以只读模式打开。 Busybox系统包括许多单独的命令,这些命令都是到主busybox可执行文件的符号链接(symbolic link)。

10-07 19:32
查看更多