Squ*_*rel 64 linux bash shell sh
当我在我的shell中调查这个问题的答案时,我注意到,即使/bin/sh指向/bin/bash我的系统,这两个命令的行为也不同.首先,输出
ls -lh /bin/sh
Run Code Online (Sandbox Code Playgroud)
是:
lrwxrwxrwx 1 root root 4 Apr 22 2013 /bin/sh -> bash*
Run Code Online (Sandbox Code Playgroud)
但是,通过以下方式调用以下命令/bin/sh:
/bin/sh -c "script.sh 2> >( grep -v FILTER 2>&1 )"
Run Code Online (Sandbox Code Playgroud)
返回此错误:
/bin/sh: -c: line 0: syntax error near unexpected token '>'
/bin/sh: -c: line 0: 'script.sh 2> >( grep -v FILTER 2>&1 )'
Run Code Online (Sandbox Code Playgroud)
通过/bin/bash以下命令运行相同的命令:
/bin/bash -c "script.sh 2> >( grep -v FILTER 2>&1 )"
Run Code Online (Sandbox Code Playgroud)
执行成功,这是输出:
This should be on stderr
Run Code Online (Sandbox Code Playgroud)
供参考,以下是以下内容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
Run Code Online (Sandbox Code Playgroud)
为什么两个调用的行为不同?
Kei*_*son 79
bash查看$argv[0](bash在C中实现)的值以确定它是如何被调用的.
其行为时援引为sh被记录在手册中:
如果使用名称调用Bash
sh,它会尽可能地模仿历史版本的启动行为sh,同时也符合POSIX标准.当作为交互式登录shell或具有该
-login选项的非交互式shell调用时,它首先尝试以该顺序从/etc/profile和读取和执行命令~/.profile.该--noprofile选项可用于抑制此行为.当作为具有名称的交互式shell调用时sh,Bash查找变量ENV,如果已定义则展开其值,并使用展开的值作为要读取和执行的文件的名称.由于调用的shellsh不会尝试从任何其他启动文件读取和执行命令,因此该--rcfile选项无效.使用该名称调用的非交互式shellsh不会尝试读取任何其他启动文件.调用时
sh,Bash在读取启动文件后进入POSIX模式
有一个很长的列表(目前有46个项目)bash在POSIX模式下会发生变化,在此处记录.
(POSIX模式可能主要用作测试脚本以便可移植到非bashshell的方法.)
顺便提一下,根据调用它们的名称改变其行为的程序是相当普遍的.某些版本的grep,, fgrep和egrep实现为单个可执行文件(尽管GNU grep不这样做).view通常是vi或的象征性链接vim; 调用它作为view以只读模式打开的原因.所述Busybox的系统包括许多与所有符号链接到主各个命令的busybox可执行文件.
koj*_*iro 20
调用bash sh会导致它在读取通常读取的启动文件后进入posix模式(与POSIX sh读取的启动文件相反).Bash有许多不同的调用模式.您可以从INVOCATION手册部分了解这些模式.以下是有关POSIX模式的一些细节.
这种模式意味着bash将在不同程度上尝试符合POSIX期望.正如这里所解释的那样,bash对这种模式有几种不同的调用,其含义略有不同:
sh:Bash在读取启动文件后进入POSIX模式.bash --posix:Bash 在读取启动文件之前进入POSIX模式.set -o posix:Bash切换到POSIX模式.POSIXLY_CORRECT:如果此变量在bash启动时处于环境中,则shell会在读取启动文件之前进入posix模式,例如bash --posix.如果在bash运行时设置,就像set -o posix.