为什么“$$”在 bash 管道中不会改变?他们不启动子流程吗?

为什么“$$”在 bash 管道中不会改变?他们不启动子流程吗?

我运行了以下代码:

echo $$
# Output : 3911
true | while true; do
    eval 'echo $$'
    break
done
# Output : 3911

文档说 while 循环(涉及管道)在子进程中运行,在这种情况下,两个进程 id 应该不同吗?

答案1

即使您在子 shell 中检查$$in的值,它的值也将保持不变。bash此行为是由POSIX 标准:

$

扩展为所调用 shell 的十进制进程 ID。在子 shell [...] 中,$应扩展为与当前 shell 相同的值。

您可能应该改用$BASHPID。以下内容摘自bash手册:

BASHPID

扩展为当前 bash 进程的进程 ID。 这与$$某些情况下不同,例如不需要重新初始化 bash 的子 shell。 赋值 BASHPID没有效果。如果BASHPID未设置,即使随后重置,它也会失去其特殊属性。

重写您的代码以$BASHPID改为使用:

printf '%s\n' "$BASHPID"
true | while true; do
    printf '%s\n' "$BASHPID"
    break
done

运行此命令将输出两个不同的 PID。

相关内容