编辑:
我在下面关于sed 's@^@ @' <(f1)
的评论不正确
虽然$BASH_SUBSHELL
表示我们与启动处于同一级别,但变量在主脚本中丢失。
根据Gordons的回答,我测试了f1 > >(sed 's@^@ @')
,而且似乎工作正常。不过,对于第一种形式,BASH_SUBSHELL不应该是1而不是0吗?
考虑这个小测试
#!/bin/bash
declare -i i=0
function f1()
{
let i++
echo "In f1, SUBSHELL: $BASH_SUBSHELL, i=$i" >&2
}
f1
f1 | sed 's@^@ @'
echo "at end, i=$i"
使用以下输出:
In f1, SUBSHELL: 0, i=1
In f1, SUBSHELL: 1, i=2
at end, i=1
(sed
的目的只是为了管道,不要指望它做什么,因为f1输出到stderr)
函数f1记录当前的BASH_SUBSHELL和当前的值
我知道为什么在脚本结尾处我们得到i=1
,因为第二次调用是在子shell中,并且子shell 1中i的值丢失了。
我不知道为什么管道的左侧没有在当前的shell中执行
虽然我认为我可以通过sed 's@^@ @' <(f1)
避免这种情况
我想知道为什么左侧与主脚本不在同一级别
答案 0 :(得分:17)
从bash man page:“管道中的每个命令都作为一个单独的进程执行(即在子shell中)。”我想可以在当前shell中执行管道的一个组件(即第一个,或者最后一个,或者可能是中间的一个),它不会像这样播放收藏夹:它们 all 在子shell中执行。如果您修改脚本如下:
#!/bin/bash
declare -i i=0
function f1()
{
let i++
echo "In f1, SUBSHELL: $BASH_SUBSHELL, i=$i" >&2
}
f1
f1 | f1 | f1
echo "at end, i=$i"
打印:
In f1, SUBSHELL: 0, i=1
In f1, SUBSHELL: 1, i=2
In f1, SUBSHELL: 1, i=2
In f1, SUBSHELL: 1, i=2
at end, i=1
因为管道中f1的所有3次调用都在子shell中运行。
答案 1 :(得分:-1)
如果有人关心,这是一个非常简洁的例子:
cd / && cd /tmp/ | pwd ; pwd
/
/
或者:
cd / && cd /tmp/ | cd /var/ ; pwd
/
是的,这一页说明了一切
http://linux.die.net/man/1/bash#管道中的每个命令都作为一个单独的进程执行(即在子shell中)。