14

编辑:

我在下面关于 sed 's@^@ @' <(f1)不正确的评论虽然$BASH_SUBSHELL表明我们与启动处于同一级别,但变量在主脚本中丢失了。根据戈登斯的回答,我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 的当前值

我知道为什么在我们得到的脚本末尾,这i=1是因为第二次调用是在一个子shell中,并且子shell 1 处的 i 的值丢失了。

我不知道的是为什么管道的左侧没有在当前的shell中执行

虽然我认为我可以避免这种情况,但sed 's@^@ @' <(f1) 我想知道为什么左侧与主脚本不在同一级别

4

2 回答 2

26

来自bash 手册页:“管道中的每个命令都作为一个单独的进程(即,在子 shell 中)执行。” 我想有可能在当前 shell 中执行管道的一个组件(即第一个,或最后一个,或者可能在中间的一个),它不会像这样播放收藏夹:它们在子 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 中运行。

于 2011-04-22T22:59:37.437 回答
-1

如果有人关心,这是一个非常简洁的示例:

cd / && cd /tmp/ | pwd  ; pwd
/
/

或者 :

cd / && cd /tmp/ | cd /var/  ; pwd
/

是的,这个页面说明了一切

http://linux.die.net/man/1/bash# Each command in a pipeline is executed as a separate process (i.e., in a subshell).

于 2014-02-26T22:26:13.303 回答