Left side of pipe is the subshell?

一笑奈何 提交于 2019-12-28 02:53:07

问题


Edit:

My comment below regarding sed 's@^@ @' <(f1) is incorrect While $BASH_SUBSHELL indicates that we are in the same level as the launch, the variables are lost in the main script. based on Gordons answer I tested f1 > >(sed 's@^@ @') instead and that seems to work correctly. Still, shouldn't BASH_SUBSHELL should be 1 and not 0 for the first form?


Consider this small test

#!/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"

with the following output:

In f1, SUBSHELL: 0, i=1
In f1, SUBSHELL: 1, i=2
at end, i=1

(the purpose of the sed is just to have a pipe to something, don't expect it to do anything because f1 outputs to stderr)

The function f1 logs the current BASH_SUBSHELL and the current value of i

I know why at the end of the script we get i=1, its because the second invocation was in a subshell, and the value of i at subshell 1 was lost.

What I don't know is why the left side of the pipe was not executed in the current shell

Though I figured that I could avoid this with sed 's@^@ @' <(f1) I would like to know why the left side is not at the same level as the main script


回答1:


From the bash man page: "Each command in a pipeline is executed as a separate process (i.e., in a subshell)." I suppose it would be possible to execute one component of a pipeline in the current shell (i.e. the first, or the last, or maybe one in the middle), it doesn't play favorites like this: they all execute in subshells. If you modify your script like this:

#!/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"

it prints:

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

because all 3 invocations of f1 in the pipeline run in subshells.




回答2:


Here is a much concise example if someone cares :

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

Or :

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

Yes this page says it all

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



来源:https://stackoverflow.com/questions/5760640/left-side-of-pipe-is-the-subshell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!