Reputation: 18243
I use ps ef
and ps rf
a lot.
Here is a sample output for 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 process of uwsgi in a script (so I want only 15237 but not 15293 nor 15294).
As of today, I tried some ps rf | grep -v ' \\_ '
... but I would like a cleaner way.
I also came accross another solution from unix.com's forums:
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 pipes and ugly tricks.
Is there really no ps
option or cleaner tricks (maybe using awk) to accomplish that?
Upvotes: 12
Views: 28674
Reputation: 317
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 '$1>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:
| cut -f2 -d: | cut -f2 -d- |
Upvotes: 0
Reputation: 91
/usr/bin/pgrep -o <process_name>
where '-o' is the oldest (least recently started) of the matching processes
Upvotes: 9
Reputation: 1
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.
ps h -opid -C<commandname> | head -1
Upvotes: 0
Reputation: 9
It is an other solution to get master process ID of a process.Tall, but nice.
pstree -p 1 |grep <proc_name>|sed -n 1p|tr -d "|,-"|sed 's/(/ /g'|sed 's/)/ /g'|tr -d "+"|awk {'print $2'};
Upvotes: 0
Reputation: 33
From key words KEYWORD
ps aux | grep -i KEYWORD | grep -v grep | awk '{print $2}'|sort -h|head -1|xargs kill
BTW, is this assumption that parent process ID is the smallest ID valid????
Upvotes: -1
Reputation: 68110
Another solution (from here):
ps -ocommand= -p $PPID | awk -F/ '{print $NF}' | awk '{print $1}'
Upvotes: 1
Reputation: 12933
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 .
Using ps for that kind of things is highly unreliable (race conditions all over the place, and special cases invalidating parsing rules...)
Upvotes: 0
Reputation: 17594
After discussing with @netcoder on his answer's comments he used a nice trick :D
Using f
on ps
will always get the parent on top which is great.
This should just work:
$ ps hf -opid -C <process> | awk '{ print $1; exit }'
as I mention on the comments, this will return the pid
of just one process.
I would go with:
ps rf -opid,cmd -C <process-name> | awk '$2 !~ /^[|\\]/ { print $1 }'
that is:
r
(or e
if you want everything)f
-opid,cmd
-C <process>
and then
-opid,cmd
) - does not start with a \
or |
then it is a parent process, so print the 1st field - which is the 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 '$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
Upvotes: 16