Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- https://www.commandlinefu.com/commands/view/22588/kill-all-zombie-processes-one-liner
- The above link suggests the following recipe for cleaning up zombie processes:
- ps axo state,ppid | awk '!/PPID/$1~"Z"{print $2}' | xargs -r kill -9
- This is functionally inefficient because awk is instructed to test each/every line for "PPID" when only the first line matches this criterion.
- Here is some sample output:
- $ ps axo state,ppid
- STAT PPID
- SsJ 1
- SsJ 1
- IsJ 1
- SsJ 1
- IsJ 1
- SsJ 1
- IJ 2140
- IsJ 2145
- SJ 43653
- IJ 2140
- IJ 2140
- SJ 2140
- IJ 2140
- IJ 2140
- IJ 2140
- IJ 2140
- IJ 2140
- IJ 2140
- SsJ 43655
- TJ 43656
- SZJ 1
- R+J 43656
- There's no reason to test every line for PPID when you can either:
- 1. Instruct ps to not print the header.
- The "-o field1[,field2,...]" option of ps supports alternative syntax "-o field1=field1_header [-o field2=field2_header ...]". Thus, the following incantation tells ps to not print the header:
- $ ps ax -o state= -o ppid=
- SsJ 1
- SsJ 1
- IsJ 1
- SsJ 1
- IsJ 1
- SsJ 1
- IJ 2140
- IsJ 2145
- SJ 43653
- IJ 2140
- IJ 2140
- SJ 2140
- IJ 2140
- IJ 2140
- IJ 2140
- IJ 2140
- IJ 2140
- IJ 2140
- SsJ 43655
- TJ 43656
- SZJ 1
- R+J 43656
- But this can be shortened using shell brace-expansion features:
- $ ps ax -o{state,ppid}=
- We can shorten this by one more letter, because the "state" field in ps can also be addressed as "stat":
- $ ps ax -o{stat,ppid}=
- SsJ 1
- SsJ 1
- IsJ 1
- SsJ 1
- IsJ 1
- SsJ 1
- IJ 2140
- IsJ 2145
- SJ 43653
- IJ 2140
- IJ 2140
- SJ 2140
- IJ 2140
- IJ 2140
- IJ 2140
- IJ 2140
- IJ 2140
- IJ 2140
- SsJ 43655
- TJ 43656
- SZJ 1
- R+J 43656
- Since there is no more header produced from ps, you can shorten the awk from this:
- awk '!/PPID/$1~"Z"{print $2}'
- to this:
- awk '$1~"Z"{print $2}'
- Transforming the initial command to:
- $ ps ax -o{stat,ppid}= | awk '$1~"Z"{print $2}' | xargs -r kill -9
- NOTE: Avoide the temptation to do "ps axo stat=,ppid=" because on some Operating Systems this tells ps that you want the field "stat" with a header of ",ppid=" (you won't get the ppid field).
- 2. The other technique is to let ps produce the header but have awk eat it immediately before processing the remainder of the lines on stdin.
- awk's "getline" built-in will read a line from stdin and set $0, NF, and $num (where num is a number from 1 to NF). Simply doing the following is enough to get awk to eat the header so that the remainder of the lines can be processed without the unnecessary check for "PPID" (to skip the header).
- $ ps axo stat,ppid | awk 'BEGIN{getline}$1~"Z"{print $2}' | xargs -r kill -9
- ===
- Now, given the two potential options:
- $ ps ax -o{stat,ppid}= | awk '$1~"Z"{print $2}' | xargs -r kill -9
- or
- $ ps axo stat,ppid | awk 'BEGIN{getline}$1~"Z"{print $2}' | xargs -r kill -9
- Compared to the original:
- $ ps axo state,ppid | awk '!/PPID/$1~"Z"{print $2}' | xargs -r kill -9
- Any/all of these can be optimized slightly further.
- The output of ps is such that the second column will only-ever be numeric and thus the only column that could potentially carry a "Z" (what we're looking for to find zombied processes), there is no need to test $1 specifically.
- That is to say the above test:
- $ ps ax -o{stat,ppid}= | awk '$1~"Z"{print $2}' | xargs -r kill -9
- Can be rewritten as:
- $ ps ax -o{stat,ppid}= | awk '/Z/{print $2}' | xargs -r kill -9
Add Comment
Please, Sign In to add comment