当前位置: 首页 > 面试题库 >

为什么/ bin / sh的行为与/ bin / bash有所不同,即使一个指向另一个?

温嘉赐
2023-03-14
问题内容

当我在外壳中研究这个问题的答案时,我注意到,即使/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被记录在手册中:

如果使用name调用Bash sh,则它会尝试sh尽可能接近于历史版本的启动行为,同时还要符合POSIX标准。

当作为交互式登录外壳程序或带有该-login选项的非交互式外壳程序调用时,它首先尝试按此顺序从/etc/profile和读取和执行命令~/.profile。该
--noprofile选项可用于禁止此行为。当作为具有名称的交互式shell调用时sh,Bash查找变量ENV,如果定义了变量
,则扩展其值,并将扩展后的值用作要读取和执行的文件的名称。由于以as身份调用的shell sh
不会尝试从任何其他启动文件读取和执行命令,因此该--rcfile选项无效。使用该名称调用的非交互式外壳程序sh不会尝试读取任何其他启动文件。


当以方式调用时sh,Bash在读取启动文件后进入POSIX模式。

bash在POSIX模式下,一长串(目前有46项)更改的内容在此处记录。

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

顺便说一句,根据调用它们的名称更改其行为的程序是相当普遍的。有些版本grepfgrep以及egrep作为一个可执行实现(虽然GNU
grep并没有这样做)。view通常是指向vi或的符号链接vim;调用它作为view导致以只读模式打开的原因。所述Busybox的系统包括许多与所有符号链接到主各个命令的busybox可执行文件。



 类似资料:
  • 我在许多地方看到过,包括本网站上的建议(首选的Bash shebang是什么?),使用而不是。我甚至看到一个有进取心的人建议使用是错误的,这样做会丢失bash功能。 尽管如此,我在一个严格控制的测试环境中使用bash,在这个环境中,循环中的每个驱动器本质上都是单个主驱动器的克隆。我理解可移植性的论点,尽管它不一定适用于我的情况。是否还有其他理由选择而不是替代方案?假设考虑可移植性,是否有理由使用它

  • 在Bash脚本的头中,这两个语句之间有什么区别: >

  • 问题内容: 在Bash脚本的标头中,这两个语句之间有什么区别: 当查阅 手册页时,得到以下定义: 这是什么意思? 问题答案: 运行命令,通过具有寻找不管程序的默认版本是在当前的利益 ENV ironment。 这样,您不必在系统上的特定位置查找它,因为这些路径可能在不同系统上的不同位置。只要它在您的路径中,它就会找到它。 缺点是,如果您希望支持Linux,则将无法传递多个参数(例如,您将无法编写)

  • 类别:账户余额 我已经把这两个类都放在Balance.java和Account tBalance.java.这两个文件都在E:/程序/MyPack. Balance.java编译没有错误但是当我编译Account tBalance.java它给出错误:找不到符号"平衡". 我无法弄清楚为什么当两个类都在同一个包中声明时? 我正在使用javac B从MyPack编译alance.javajavac

  • 因此,我试图在Dockerfile中安装OpenJDK,但遇到了一些问题。它总是以以下消息出错:,然后在。这是执行失败的命令。目前在Ubuntu 20.04VM上 这是一个用5.0编写的Visual Studio项目,需要执行一个。jar文件。这些似乎没有帮助:apt-get update'返回了一个非零代码:100,Docker File非零代码100错误。最好是Java13,但这个问题阻止了我

  • 问题内容: 我正在使用以下命令构建新的Docker映像: 但是,它失败并显示以下错误: 这似乎在我的本地计算机(Mac OSX)上运行良好,但是当我尝试在Linux CentOS 7计算机上构建它时,它失败了。 问题答案: 最后,我们升级了项目以使用此Docker Maven插件:https : //github.com/fabric8io/fabric8-maven- plugin 。到目前为止