ps:干净的方式只获得父进程?

我使用ps efps 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 ... 

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

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

我也来自unix.com的论坛的另一个解决scheme:

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

但是还有很多pipe道丑陋的技巧

是否真的没有ps选项或清洁技巧(也许使用awk )来完成?

在与@netcoder讨论他的答案的评论后,他用了一个很好的把戏:D
ps上使用f将始终得到顶部的父母,这是伟大的。

这应该只是工作:

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

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


我会去:

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

那是:

  • 列表运行过程r (或者如果你想要的一切)
  • 与父母/子女图一起f
  • 只输出pid和命令名称-opid,cmd
  • 只针对给定的进程-C <process>

接着

  • 如果第二个字段(命令( -opid,cmd ))不是以\| 那么这是一个父进程,所以打印第一个字段 – 这是pid。

简单测试:

 $ 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 '$2 !~ /^[|\\]/ { print $1 }' PID 2800 2794 $ # also supressing the header of ps (top line 'PID') -- add 'h' to ps $ ps hf -opid,cmd -Cchromium | awk '$2 !~ /^[|\\]/ { print $1 }' 2800 2794 
 /usr/bin/pgrep -o <process_name> 

其中“-o”是最早的(最近最少开始的)匹配过程

你为什么不直接使用–pidfile选项将主文件的pid保存在一个文件(pidfile)中? 如果这不是一个可行的解决方案,您可以使用–procname-master为主进程提供一个自定义名称。

使用ps来处理这类事情是非常不可靠的(各地的竞争条件,以及使解析规则无效的特殊情况…)

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

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

获得一个进程的主进程ID是另一种解决方法。

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

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

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

从关键词KEYWORD

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

顺便说一句,这是假设父进程ID是最小的ID有效吗?