如何在命令行上获取 bash 子进程的进程 ID
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9119885/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get the process id of a bash subprocess on command line
提问by anubhava
I know in bash we can create subshells using round parenthesis (and ). As per bash man page:
我知道在 bash 中我们可以使用圆括号(和). 根据 bash 手册页:
(list) list is executed in a subshell environment
Also to get the current process idwe use:
还要获取我们使用的当前进程 ID:
echo $$
Now my question is how to get process id of a subshell created using (and )on command line?
现在我的问题是如何获取使用(和)在命令行上创建的子shell的进程ID ?
If I use this:
如果我使用这个:
echo $$; ( echo $$; )
I will get the parent shell's process id printed twiceon stdout since $$gets expanded even before subshell is created. So how to really force the lazy expansion?
我将在 stdout 上打印两次父 shell 的进程 ID,因为$$即使在创建子 shell 之前它也会被扩展。那么如何真正强制惰性扩展呢?
[Solution should work on Mac as well not just Linux]
[解决方案不仅适用于 Linux,也适用于 Mac]
Update:
更新:
Suggested linked answer doesn't work since echo $BASHPIDdoes not workon my Mac and returns blank.
建议的链接答案不起作用,因为在我的 Mac 上echo $BASHPID不起作用并返回空白。
采纳答案by anubhava
Thanks to all of you for spending your valuable time in finding answer to my question here.
感谢大家花费宝贵的时间在这里寻找我的问题的答案。
However I am now answering my own question since I've found a hackway to get this pid on bash ver < 4 (will work on all the versions though). Here is the command:
但是,我现在正在回答我自己的问题,因为我找到了一种在 bash ver < 4 上获取此 pid的黑客方法(尽管适用于所有版本)。这是命令:
echo $$; ( F='/tmp/myps'; [ ! -f $F ] && echo 'echo $PPID' > $F; )
It prints:
它打印:
5642
13715
Where 13715 is the pid of the subshell. To test this when I do:
其中 13715 是子外壳的 pid。当我这样做时要测试这个:
echo $$; ( F='/tmp/myps'; [ ! -f $F ] && echo 'echo $PPID' > $F; bash $F; ps; )
I get this:
我明白了:
5642
13773
PID TT STAT TIME COMMAND
5642 s001 S 0:02.07 -bash
13773 s001 S+ 0:00.00 -bash
Telling me that 13773 is indeed the pid of the subshell.
告诉我 13773 确实是子外壳的 pid。
Note:I reverted back to my original solution since as @ChrisDodd commented that echo $$; ( bash -c 'echo $PPID'; )doesn't work Linux. Above solution of mine works both on Mac and Linux.
注意:我恢复到我原来的解决方案,因为@ChrisDodd 评论说这echo $$; ( bash -c 'echo $PPID'; )不适用于 Linux。我的上述解决方案适用于 Mac 和 Linux。
回答by Chris Dodd
Unfortunately there's no easy way to do this prior to bash version 4, when $BASHPID was introduced. One thing you can do is to write a tiny program that prints its parent PID:
不幸的是,在引入 $BASHPID 的 bash 版本 4 之前没有简单的方法可以做到这一点。您可以做的一件事是编写一个打印其父 PID 的小程序:
int main()
{
printf("%d\n", getppid());
return 0;
}
If you compile that as ppidand put it in your path, you can call it, eg:
如果您ppid将其编译为并将其放在您的路径中,则可以调用它,例如:
$ (echo $$; ppid)
2139
29519
$ (x=$(ppid); echo $x)
29521
One oddness I noticed, however, is that if you write
然而,我注意到的一个奇怪之处是,如果你写
$ (ppid)
it doesn't seem to actually run it in a subshell -- you need at least two commands inside the parentheses for bash to actually run them in a subshell.
它似乎并没有在子shell中实际运行它——你需要在括号内至少有两个命令,bash才能在子shell中实际运行它们。
回答by Zulu
You can do :
你可以做 :
$ ( your_action ) &
[1] 44012
And find subprocess' PID like that :
并像这样找到子进程的PID:
$ echo "The sub PID : $!"
The Sub PID : 44012
$!returns the last job in background's PID. (see this manual)
$!返回后台 PID 中的最后一个作业。(见本手册)
回答by Gerald Boersma
Use homebrew to install pgrep on the Mac: brew install pgrep
在 Mac 上使用 homebrew 安装 pgrep: brew install pgrep
Check out http://mxcl.github.com/homebrew/to install Homebrew.
查看http://mxcl.github.com/homebrew/安装 Homebrew。
回答by masseo
This seems like it works:
这似乎有效:
(echo $$; echo `ps axo pid,command,args | grep "$$" |awk '{ getline;print }'`)
14609
17365
For whatever reason, OSX is limited and doesnt come with pgrep, or one could do (which works in Linux):
无论出于何种原因,OSX 是有限的并且不带有 pgrep,或者可以这样做(在 Linux 中有效):
(echo $$; echo `pgrep -P $$`)
14609
17390
回答by masseo
You can use the ppidof the parent by echoing out the BASHPIDof the parent when you first enter the shell, then you background the process and can look up the pidvia ppidusing the parent pid.
您可以使用ppid呼应出父BASHPID父的当您第一次输入shell,那么你后台进程,可以查找pid通过ppid使用父pid。
E.g. To get the pid of a sleep 555command backgrounded within a subshell:
例如,要获取sleep 555子 shell 中后台命令的 pid :
(echo "$BASHPID" > /tmp/_tmp_pid_ && sleep 555 &) && ps -ho pid --ppid=$(< /tmp/_tmp_pid_)
(echo "$BASHPID" > /tmp/_tmp_pid_ && sleep 555 &) && ps -ho pid --ppid=$(< /tmp/_tmp_pid_)

