如何在命令行上获取bash子进程的进程id

anu*_*ava 30 unix macos bash shell process

我知道在bash我们可以创建一个使用圆括号子shell ().根据bash手册页:

(list) list  is  executed  in  a  subshell environment 
Run Code Online (Sandbox Code Playgroud)

另外,要获取当前进程ID,我们使用:

echo $$
Run Code Online (Sandbox Code Playgroud)

现在我的问题是如何获取使用()命令行创建的子shell的进程ID ?

如果我用这个:

echo $$; ( echo $$; ) 
Run Code Online (Sandbox Code Playgroud)

我会在stdout上打印两次父shell的进程id,因为$$甚至在创建subshel​​l之前就会进行扩展.那么如何真正强迫懒惰的扩张呢?

[解决方案应该适用于Mac,而不仅仅是Linux]

更新:

建议的链接答案不起作用,因为在我的Mac上echo $BASHPID 不起作用并返回空白.

anu*_*ava 19

感谢大家花了宝贵的时间在这里找到我的问题的答案.

但是我现在正在回答我自己的问题,因为我发现了一个hack方法来获取bash ver <4上的这个pid(虽然可以在所有版本上工作).这是命令:

echo $$; ( F='/tmp/myps'; [ ! -f $F ] && echo 'echo $PPID' > $F; )
Run Code Online (Sandbox Code Playgroud)

它打印:

5642
13715
Run Code Online (Sandbox Code Playgroud)

其中13715是子壳的pid.为了测试这个,当我这样做:

echo $$; ( F='/tmp/myps'; [ ! -f $F ] && echo 'echo $PPID' > $F; bash $F; ps; )
Run Code Online (Sandbox Code Playgroud)

我明白了:

5642
13773
  PID   TT  STAT      TIME COMMAND
 5642 s001  S      0:02.07 -bash
13773 s001  S+     0:00.00 -bash
Run Code Online (Sandbox Code Playgroud)

告诉我13773确实是子壳的pid.

注意:我恢复了原来的解决方案,因为@ChrisDodd评论说echo $$; ( bash -c 'echo $PPID'; )Linux不起作用.我的上述解决方案适用于Mac和Linux.

  • @ChrisDodd命令组不在子shell中运行,因为它的命令列表只包含一个命令(这是一个未记录的优化).使用`echo $$; (:; bash -c'echo $ PPID')`强制子shell. (6认同)
  • `sh -c'echo $ PPID`'是一种较短的方法 (3认同)
  • 一个奇怪的是:当我运行`echo $$; (bash -c'echo $ PPID';)`在我的电脑上(Linux),它打印相同的pid两次...... (3认同)

Chr*_*odd 7

不幸的是,在引入$ BASHPID之前,在bash版本4之前没有简单的方法可以做到这一点.你可以做的一件事是编写一个打印其父PID的小程序:

int main()
{
    printf("%d\n", getppid());
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果ppid将其编译为并将其放入路径中,则可以调用它,例如:

$ (echo $$; ppid)
2139
29519
$ (x=$(ppid); echo $x)
29521
Run Code Online (Sandbox Code Playgroud)

然而,我注意到的一个奇怪的是,如果你写的话

$ (ppid)
Run Code Online (Sandbox Code Playgroud)

它似乎并没有在子shell中实际运行 - 你需要在括号内至少有两个命令让bash实际在子shell中运行它们.


Zul*_*ulu 5

你可以做 :

$ ( your_action ) &
[1] 44012
Run Code Online (Sandbox Code Playgroud)

并像这样找到子进程的PID:

$ echo "The sub PID : $!"
The Sub PID : 44012
Run Code Online (Sandbox Code Playgroud)

$!返回后台 PID 中的最后一个作业。(见本手册