10

我用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 ' \\_ '......但我想要一种更清洁的方式

我还从 unix.com 的论坛中发现了另一个解决方案:

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

但仍然有很多管道丑陋的伎俩

真的没有ps选择或更清洁的技巧(可能使用awk)来实现吗?

4

8 回答 8

13

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

这应该只是工作:

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

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


我会去:

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

那是:

  • 列出正在运行的进程r(或者e如果你想要一切)
  • 连同父/子图f
  • 只输出 pid 和命令名-opid,cmd
  • 仅适用于给定的过程-C <process>

进而

  • 如果第二个字段 - 即命令 ( -opid,cmd) - 不以 a 开头,\或者|它是父进程,则打印第一个字段 - 即 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
于 2012-09-11T15:48:34.827 回答
7
/usr/bin/pgrep -o <process_name>

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

于 2017-05-31T15:00:06.840 回答
1

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

ps -ocommand= -p $PPID | awk -F/ '{print $NF}' | awk '{print $1}'
于 2014-04-04T10:12:04.453 回答
0

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

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

于 2012-09-11T17:45:46.987 回答
0

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

pstree -p 1 |grep <proc_name>|sed -n 1p|tr -d "|,-"|sed 's/(/ /g'|sed 's/)/ /g'|tr -d "+"|awk {'print $2'};
于 2016-06-15T11:45:16.670 回答
0

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

ps h -opid -C<commandname> | head -1
于 2017-01-15T22:13:07.060 回答
0

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

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 '$1>0' | wc -l

编辑:我以前用过

| cut -f1 -d: |

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

| cut -f2 -d: | cut -f2 -d- |
于 2019-09-02T15:03:20.110 回答
-1

从关键词KEYWORD

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

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

于 2015-09-11T06:29:05.783 回答