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