为什么/bin/sh 的行为与/bin/bash 不同,即使一个指向另一个? [英] Why does /bin/sh behave differently to /bin/bash even if one points to the other?

查看:37
本文介绍了为什么/bin/sh 的行为与/bin/bash 不同,即使一个指向另一个?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我在 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 of sh 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.)

顺便说一下,根据调用它们的名称来改变其行为的程序相当普遍.某些版本的 grepfgrepegrep 被实现为单个可执行文件(尽管 GNU grep 没有做这个).view 通常是到 vivim 的符号链接;将其作为 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆