如何在bash中列出所有后台进程的pid

21

我可能表达不清或者答案不容易找到!但是我正在试图找出如何列出所有后台任务PID。例如:

到目前为止,我发现要列出最后一个PID,我们使用:

$!

但现在我想列出该任务之前的PID(如果存在),但我找不到如何做到这一点。最终,我想列出所有我的后台任务PID。

我知道我们也可以使用以下命令找到上一个作业的ID:

%% (last job in list)
%1 (first job in list)
%2 (second job in list)

但是对于进程ID似乎不起作用?

谢谢大家:)

4个回答

34
使用ps S命令。例如:
$ vim &
[1] 8263
$ ipython &
[2] 8264
$ ps S
 PID TTY      STAT   TIME COMMAND
 3082 pts/0    Ss     0:00 bash
 3137 pts/0    Sl+    0:00 python /usr/bin/ipython
 8207 pts/2    Ss     0:00 bash
 8263 pts/2    T      0:00 vim
 8264 pts/2    Tl     0:00 python /usr/bin/ipython
 8284 pts/2    Tl     0:00 python /usr/bin/ipython
 8355 pts/2    R+     0:00 ps S

如果您想获取PID,请使用以下方法:

$ ps S | awk '{print  $  1 }' | grep -E '[0-9]'
3082
3137
8207
8263
8264
8284
8357
8358
835

您也可以使用 jobs -l 命令, 但是它只显示当前会话的后台进程。


2
ps S 在我的 shell 中会给出一个巨大的列表(包括来自兄弟 shell 的子进程等)。但是 ps --ppid $$ 对我来说很好用。 - Alfe
1
我借鉴了这个非常棒的想法(谢谢!+1),并对其进行了修改,以更贴近我的目的:list=\ps S | grep "search-string" | awk '{print $ 1}'``。现在,我可以使用存储在$list中的结果来循环执行这些任务 :) - code_fodder
@code_fodder 我也曾经考虑过你想要的 grep "search-string",但是你只写了 PID。 - Michael Kazarian
@MichaelKazarian 是的,我知道:),我使用grep作为过滤器,只是为了从它们的“长”描述中找到我想要的PID。基本上与您所做的相同,但如果您先执行“awk”,那么我们只有原始PID可以进行字符串搜索。不过,这只是微小的差异,谢谢! - code_fodder
都对。这里的答案不应只限于Linux,并且 --ppid 对我很有效 ;- ) - Alfe
显示剩余2条评论

15
但是同样的方法似乎不适用于进程ID?您可以尝试使用“jobs -l”或“-p”命令。使用“-l”和“-p”开关将导致“jobs”命令输出进程ID。

这绝对有效...谢谢 :),但我想能够像使用%1、%2命令一样单独访问它们。有这样的方法吗? - code_fodder
@code_fodder 你可能想要通过一个 while read 循环将 jobs 命令的输出进行管道传输,并获取每一行。 - cnicutar
如果在另一个控制台/终端/Shell中发出jobs -l命令,则该命令不起作用,因为jobs命令仅显示当前Shell会话中运行的作业。 - Vic VKh

5
在bash中,与tcsh类似的命令是jobs -l(长格式)。
[ghoti@pc ~]$ sleep 300 &
[1] 33811
[ghoti@pc ~]$ sleep 301 &
[2] 33812
[ghoti@pc ~]$ sleep 302 &
[3] 33813
[ghoti@pc ~]$ jobs -l
[1]- 33811 Running                 sleep 300 &
[2]- 33812 Running                 sleep 301 &
[3]+ 33813 Running                 sleep 302 &
[ghoti@pc ~]$ 

这绝对有效...谢谢 :),但我想能够像使用%1、%2命令一样单独访问它们。有这样的方法吗?(与cnicutar的评论相同) - code_fodder

1
如果您想查看不再由shell作为作业处理的子进程(例如,因为您故意使用disown或类似方法将它们取消),则您可以使用此方法查找所有以为父级的进程:
grep "PPid:.*$$" /proc/[0-9]*/status | cut -d/ -f3

也就是说
ps --ppid $$

可以派上用场。(感谢@Michael Kazarian在这里也有一个答案。)

谢谢你的回答,这也可以,但我更喜欢迈克尔帖子中略微简单的语法。对于好的回答/评论加1。 - code_fodder
我的操作系统默认不挂载/proc,但如果我手动挂载它,/proc/[0-9]*/status中不包含任何包含Ppid:的行。如果我想要获取我的shell的父进程ID,我可以使用:ps Oppid $$将其添加到ps的输出中,或者使用ps oppid $$仅显示ppid。 - ghoti
1
是的。除了Posix(似乎没有涵盖这个问题),实际上并没有一个标准可依靠,因此在shell中编写兼容性代码很困难。最好使用Python、C或类似语言。 - Alfe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接