为什么/bin/sh 的行为与/bin/bash 不同,即使一个指向另一个? [英] Why does /bin/sh behave differently to /bin/bash even if one points to the other?
问题描述
当我在 shell 中研究 this question,我注意到,即使 /bin/sh
在我的系统上指向 /bin/bash
,这两个命令的行为也不同.首先,
While I was playing around in my shell investigating the answer to this question, I noticed that, even though /bin/sh
was pointing to /bin/bash
on my system, the two commands behave differently. First of all, the output of
ls -lh /bin/sh
是:
lrwxrwxrwx 1 root root 4 Apr 22 2013 /bin/sh -> bash*
但是,通过/bin/sh
调用以下命令:
However, invoking the following command through /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
运行相同的命令:
While running the same command through /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
为什么这两个调用的行为不同?
Why do the two invocations behave differently?
推荐答案
bash
查看$argv[0]
的值(bash是用C实现的)确定它是如何被调用的.
bash
looks at the value of $argv[0]
(bash is implemented in C) to determine how it was invoked.
它在作为 sh
调用时的行为被记录在 在手册中:
Its behavior when invoked as sh
is documented in the manual:
如果使用名称 sh
调用 Bash,它会尝试模仿启动sh
历史版本的行为尽可能接近,而也符合POSIX标准.
If Bash is invoked with the name
sh
, it tries to mimic the startup behavior of historical versions ofsh
as closely as possible, while conforming to the POSIX standard as well.
当作为交互式登录 shell 或作为非交互式登录 shell 调用时带有 -login
选项的 shell,它首先尝试读取和执行来自 /etc/profile
和 ~/.profile
的命令,按顺序排列.这--noprofile
选项可用于禁止此行为.当作为名为 sh
的交互式 shell 调用时,Bash 查找变量ENV
,如果定义了就扩展它的值,并使用扩展后的值作为要读取和执行的文件的名称.由于作为 sh
调用的 shell不尝试从任何其他启动读取和执行命令文件,--rcfile
选项无效.非交互式外壳使用名称 sh
调用不会尝试读取任何其他启动文件.
When invoked as an interactive login shell, or as a non-interactive
shell with the -login
option, it first attempts to read and execute
commands from /etc/profile
and ~/.profile
, in that order. The
--noprofile
option may be used to inhibit this behavior. When invoked as an interactive shell with the name sh
, Bash looks for the variable
ENV
, expands its value if it is defined, and uses the expanded value
as the name of a file to read and execute. Since a shell invoked as sh
does not attempt to read and execute commands from any other startup
files, the --rcfile
option has no effect. A non-interactive shell
invoked with the name sh
does not attempt to read any other startup
files.
当作为 sh
调用时,Bash 在启动文件完成后进入 POSIX 模式阅读
When invoked as sh
, Bash enters POSIX mode after the startup files are
read
当 bash
处于 POSIX 模式时,有一长串(目前有 46 项)会发生变化的事情,此处记录.
There's a long list (currently 46 items) of things that change when bash
is in POSIX mode, documented here.
(POSIX 模式可能主要用作测试脚本对非bash
shell 的可移植性的方法.)
(POSIX mode is probably useful mostly as a way to test scripts for portability to non-bash
shells.)
顺便说一下,根据调用它们的名称来改变其行为的程序相当普遍.某些版本的 grep
、fgrep
和 egrep
被实现为单个可执行文件(尽管 GNU grep
没有做这个).view
通常是到 vi
或 vim
的符号链接;将其作为 view
调用会导致以只读模式打开.Busybox 系统包括许多单独的命令,这些命令都是到主 busybox
的符号链接可执行.
Incidentally, programs that change their behavior depending on the name under which they were invoked are fairly common. Some versions of grep
, fgrep
, and egrep
are implemented as a single executable (though GNU grep
doesn't do this). view
is typically a symbolic link to vi
or vim
; invoking it as view
causes to open in read-only mode. The Busybox system includes a number of individual commands that are all symlinks to the master busybox
executable.
这篇关于为什么/bin/sh 的行为与/bin/bash 不同,即使一个指向另一个?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!