为什么是$!为后台运行的子 shell 返回错误的进程 ID?

为什么是$!为后台运行的子 shell 返回错误的进程 ID?
$(sleep 5) &
echo $!
sleep 1
echo "done"

以上输出:

$ ./test.sh
7483
done

但是,如果我搜索,sleepps aux会看到:

 ps aux | rg sleep
chris     7484  0.0  0.0 132788  1432 pts/6    S+   12:10   0:00 sleep 1
chris     7485  0.0  0.0 132788  1432 pts/6    S+   12:10   0:00 sleep 5
chris     7519  0.0  0.0  10376  5744 pts/7    S+   12:10   0:00 rg --no-ignore-vcs sleep

sleep 5 进程不是7485脚本7483的输出。这种行为的原因是什么?

答案1

$(sleep 5)

运行一个运行的 shell sleep。给出的 pid$!是 shell 的。

你不需要在这里替换,

 sleep 5 &

会给你sleep的pid。

我想sleep在你的例子中替换了其他东西,但无论如何,背景替换可能是不必要的。仅使用子外壳,

(sleep 5) &

通常会给出 的sleeppid,因为许多 shell 在运行子 shell 中的最后一个命令时将自己替换为子命令,这有效地重用了子 shell 的 pid sleep;但

(sleep 5; sleep 5) &

会给你 shell 的 pid,而不是sleep

相关内容