$!在 bash 中使用 -c 或子 shell 运行命令时为空

$!在 bash 中使用 -c 或子 shell 运行命令时为空

我正在尝试使用 获取上一个命令的 pid $!,但这仅适用于“主”shell:

$ echo "test" | echo $!
4436
$

如果我启动一个子 shell,那么它是空的:

$ bash
$ echo "test" | echo $!

$

如果我用 运行它-c,也会发生同样的情况:

$ bash -c 'echo "test" | echo $!'

$

我可以重写一些东西,或者添加选项来使其工作bash -c吗?

答案1

$!将保存最近启动的后台作业的 PID(以 结尾的命令&)。您不能按照所示的方式使用它来获取有关管道其他部分的信息。

您的管道输出数字这一事实echo "test" | echo $!仅意味着您在运行管道之前的某个时刻启动了后台作业。输出的数字与管道中的任何内容无关。在新的 shell 中,没有启动任何后台作业,该管道将不会输出任何内容。

答案2

$!是作业的 PIDshell 最后放入后台。如果你想用它做任何事情,你通常应该将它保存到一个变量中,因为运行另一个后台进程会覆盖它。在这方面$!就像这样$?,尽管它不会那么快被覆盖。

与任何其他变量一样,如果您想让子进程可以使用它,请将其导出到环境中。

background_command &
export background_command_pid=$!
bash -c 'echo "My background sibling process is $background_command_pid"'

顺便说一下,与你的说法相反,$! 保存在子shell中。

$ sleep 3 & echo $!
23791
$ { echo $! | cat; }                           
23791
$ ( echo $!; /bin/cat /dev/null; ); /bin/cat /dev/null
23791
$ echo $! $(echo $!)
23791 23791

运行另一个 bash 实例不是子 shell。你是将子 shell 与作为 shell 的子进程混淆

相关内容