Linux ps:只获取父进程的干净方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12373309/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 14:19:07  来源:igfitidea点击:

ps: Clean way to only get parent processes?

linuxbashshellcommand-lineps

提问by shkschneider

I use ps efand ps rfa lot.

我用ps efps rf很多。

Here is a sample output for ps rf:

以下是 的示例输出ps rf

  PID TTY      STAT   TIME COMMAND
 3476 pts/0    S      0:00 su ...
 3477 pts/0    S      0:02  \_ bash
 8062 pts/0    T      1:16      \_ emacs -nw ...
15733 pts/0    R+     0:00      \_ ps xf
15237 ?        S      0:00 uwsgi ...
15293 ?        S      0:00  \_ uwsgi ...
15294 ?        S      0:00  \_ uwsgi ...

And today I needed to retrieve only the master processof uwsgi in a script (so I want only 15237 but not 15293 nor 15294).

而今天我只需要在脚本中检索uwsgi的主进程(所以我只想要 15237 而不是 15293 和 15294)。

As of today, I tried some ps rf | grep -v ' \\_ '... but I would like a cleaner way.

截至今天,我尝试了一些ps rf | grep -v ' \\_ '......但我想要一种更清洁的方式

I also came accross another solution from unix.com's forums:

我还遇到了来自 unix.com 论坛的另一个解决方案:

ps xf | sed '1d' | while read pid tty stat time command ; do [ -n "$(echo $command | egrep '^uwsgi')" ] && echo $pid ; done

But still a lot of pipesand ugly tricks.

但仍然有很多管道丑陋的技巧

Is there really no psoption or cleaner tricks (maybe using awk) to accomplish that?

真的没有ps选择或更清洁的技巧(也许使用awk)来实现这一目标吗?

采纳答案by c00kiemon5ter

After discussing with @netcoder on his answer's comments he used a nice trick :D
Using fon pswill always get the parent on top which is great.

在与@netcoder 讨论他的回答评论后,他使用了一个很好的技巧:D
使用fonps将始终让父级处于领先地位,这很棒。

This should just work:

这应该只是工作:

$ ps hf -opid -C <process> | awk '{ print ; exit }'

as I mention on the comments, this will return the pidof just one process.

正如我在评论中提到的,这将仅返回pid一个进程的 。



I would go with:

我会去:

ps rf -opid,cmd -C <process-name> | awk ' !~ /^[|\]/ { print  }'

that is:

那是:

  • list running processses r(or eif you want everything)
  • along with parent/children graph f
  • output only the pid and command name -opid,cmd
  • only for the given process -C <process>
  • 列出正在运行的进程r(或者e如果你想要一切)
  • 连同父/子图 f
  • 只输出pid和命令名称 -opid,cmd
  • 仅针对给定进程 -C <process>

and then

进而

  • if the 2nd field - which is the command (-opid,cmd) - does not start with a \or |then it is a parent process, so print the 1st field - which is the pid.
  • 如果第二个字段 - 即命令 ( -opid,cmd) - 不以 a 开头,\或者|它是父进程,则打印第一个字段 - 即 pid。


simple test:

简单测试:

$ ps f -opid,cmd -Cchromium
  PID CMD
 2800 /usr/lib/chromium/chromium --type=zygote --enable-seccomp-sandbox
 2803  \_ /usr/lib/chromium/chromium --type=zygote --enable-seccomp-sandbox
 2899      \_ /usr/lib/chromium/chromium --type=renderer --enable-seccomp-sandbox --lang=en-US --force-fieldtrials=ConnCountImpact/conn_count_6/ConnnectB
 2906      |   \_ /usr/lib/chromium/chromium --type=renderer --enable-seccomp-sandbox --lang=en-US --force-fieldtrials=ConnCountImpact/conn_count_6/Connn
 [  ... snip ... ]
 2861      \_ /usr/lib/chromium/chromium --type=renderer --enable-seccomp-sandbox --lang=en-US --force-fieldtrials=ConnCountImpact/conn_count_6/ConnnectB
 2863          \_ /usr/lib/chromium/chromium --type=renderer --enable-seccomp-sandbox --lang=en-US --force-fieldtrials=ConnCountImpact/conn_count_6/Connn
 2794 /usr/lib/chromium/chromium --enable-seccomp-sandbox --memory-model=low --purge-memory-button --disk-cache-dir=/tmp/chromium
 2796  \_ /usr/lib/chromium/chromium --enable-seccomp-sandbox --memory-model=low --purge-memory-button --disk-cache-dir=/tmp/chromium
 3918  \_ /usr/lib/chromium/chromium --type=gpu-process --channel=2794.45.1891443837 --gpu-vendor-id=0x10de --gpu-device-id=0x0611 --gpu-driver-version -
25308  \_ [chromium] <defunct>
31932  \_ /usr/lib/chromium/chromium --type=plugin --plugin-path=/usr/lib/mozilla/plugins/libflashplayer.so --lang=en-US --channel=2794.1330.1990362572


$ ps f -opid,cmd -Cchromium | awk ' !~ /^[|\]/ { print  }'
PID
2800
2794

$ # also supressing the header of ps (top line 'PID') -- add 'h' to ps
$ ps hf -opid,cmd -Cchromium | awk ' !~ /^[|\]/ { print  }'
2800
2794

回答by roberto

Why do not you simply save the pid of the master in a file (pidfile) with the --pidfile option ? If it is not a viable solution you can give a custom name to the master process with --procname-master .

为什么不简单地使用 --pidfile 选项将 master 的 pid 保存在一个文件 (pidfile) 中?如果它不是一个可行的解决方案,您可以使用 --procname-master 为主进程指定一个自定义名称。

Using ps for that kind of things is highly unreliable (race conditions all over the place, and special cases invalidating parsing rules...)

将 ps 用于那种事情是非常不可靠的(到处都是竞争条件,特殊情况会使解析规则无效......)

回答by Albert

Another solution (from here):

另一个解决方案(从这里):

ps -ocommand= -p $PPID | awk -F/ '{print $NF}' | awk '{print }'

回答by carpenter

From key words KEYWORD

从关键词KEYWORD

ps aux | grep -i KEYWORD | grep -v grep | awk '{print }'|sort -h|head -1|xargs kill

BTW, is this assumption that parent process ID is the smallest ID valid????

BTW,这个假设父进程ID是最小ID有效吗????

回答by U?ur Engin

It is an other solution to get master process ID of a process.Tall, but nice.

这是获取进程的主进程 ID 的另一种解决方案。高,但很好。

pstree -p 1 |grep <proc_name>|sed -n 1p|tr -d "|,-"|sed 's/(/ /g'|sed 's/)/ /g'|tr -d "+"|awk {'print '};

回答by user2435913

If you can safely assume that you only have one parent process with n children, or that you only care about the 'earliest' of several parent processes (lowest PID), then I think this simpler solution works just fine.

如果您可以放心地假设您只有一个带有 n 个子进程的父进程,或者您只关心几个父进程中“最早的”(最低 PID),那么我认为这个更简单的解决方案工作得很好。

ps h -opid -C<commandname> | head -1

回答by Bodo

/usr/bin/pgrep -o <process_name>

where '-o' is the oldest (least recently started) of the matching processes

其中“-o”是匹配进程中最老的(最近最少启动的)

回答by reardenlife

By filename (outputs the number of parents):

按文件名(输出父母的数量):

o=""; for p in $(pgrep -f example.sh); do o="${o}$(pstree -lp | grep -nF \($p\))\n"; done; echo -e "$o" | cut -f2 -d: | cut -f2 -d- | sort -n | grep -vE ^$ | uniq -c | awk '>0' | wc -l

Edit:I previously used

编辑:我以前用过

| cut -f1 -d: |

But apparently there is no guarantee that child processes will follow one after another so I ended up with counting parent processes by their name and pid:

但显然不能保证子进程会一个接一个地跟随,所以我最终通过它们的名称和 pid 来计算父进程:

| cut -f2 -d: | cut -f2 -d- |

回答by tombak2

how about ps fuxa | grep 'PID\|[0-9] /'for all parents, or: ps fuxa | grep '[0-9] /' | grep 'PID\|<commandname>'for single process?

怎么样ps fuxa | grep 'PID\|[0-9] /'对所有的父母,或者: ps fuxa | grep '[0-9] /' | grep 'PID\|<commandname>'单进程?