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,因为$$甚至在创建subshell之前就会进行扩展.那么如何真正强迫懒惰的扩张呢?
[解决方案应该适用于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.
不幸的是,在引入$ 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中运行它们.
你可以做 :
$ ( 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 中的最后一个作业。(见本手册)
| 归档时间: |
|
| 查看次数: |
12929 次 |
| 最近记录: |