我正在尝试使用 获取上一个命令的 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
$!
是作业的 PID这shell 最后放入后台。如果你想用它做任何事情,你通常应该将它保存到一个变量中,因为运行另一个后台进程会覆盖它。在这方面$!
就像这样$?
,尽管它不会那么快被覆盖。
与任何其他变量一样,如果您想让子进程可以使用它,请将其导出到环境中。
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 的子进程混淆。