管道的左侧是子壳?

发布于 2024-11-02 19:40:25 字数 856 浏览 2 评论 0原文

编辑:

我下面关于 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 中,并且值i 在 subshel​​l 1 处的值是 丢失的。

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

尽管我认为可以使用 sed 's@^@ @' <(f1) 来避免这种情况 我想知道为什么左边和主脚本不在同一层

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

晚雾 2024-11-09 19:40:25

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 中运行。

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.

沙与沫 2024-11-09 19:40:25

如果有人关心的话,这里有一个非常简洁的例子:

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

或者:

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

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

http:// linux.die.net/man/1/bash# 管道中的每个命令都作为单独的进程(即在子shell 中)执行。

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文