2

I want to stop several processes using awk.My command is like this:

sudo ps -ef|grep wget |grep -v grep|awk '{print $2;sudo kill -STOP $2}'

I want to stop all processes which is running wget. $2 of awk means the pid of each process.But I find that it doesn't work.The state of process remains the same.They are still running.

Instead , I modified this command:

sudo ps -ef|grep wget |grep -v grep|awk '{print $2}'|xargs sudo kill -STOP

it works! So , anyone can tell me the difference of them ?

  • Do you really want to kill processes of other users? – Hauke Laging Dec 12 '14 at 3:37
5

There is a lot to be improved about your approach:

  1. On most systems (if /proc is not mounted with hidepid) you don't need root privilege for ps.

  2. There is no need for two grep instances just to get rid of the first in the process list. Do this instead: grep '[w]get'

  3. There is no use in grep filtering input for awk. awk can do that pretty well on its own: awk '/wget/ {print $2}' (or, due to the ps problem: awk '/[w]get/ {print $2}')

  4. Instead of filtering ps output and piping PIDs to kill you could just use killall wget

  5. You would call sudo once for awk and not once per input line.

The main problem in your first pipeline is the awk command: awk '{print $2;sudo kill -STOP $2}'. You can run external commands from awk but not this way. You need this awk function: system(cmd-line)

If you want to use ps and kill then do it this way:

kill -STOP $(ps -ef | awk '/[w]get/ {print $2}')
1

For improvement, see @Hauke Laging's answer.

For the difference between yours solution, the first approach does not run kill command, it just refer to four variables sudo, kill, STOP and $2.

At least in gawk, when you refer to variables with no action in a statement, it do nothing. You can easily use dgawk to see that:

$ dgawk -f test.awk
dgawk> trace on
dgawk> run
Starting program: 
[     1:0x7f8d697fffe0] Op_rule             : [in_rule = BEGIN] [source_file = test.awk]
[     2:0x7f8d697fef60] Op_push_i           : 2 [PERM|NUMCUR|NUMBER]
[     2:0x7f8d697fef40] Op_field_spec       : 
[     2:0x7f8d697fef20] Op_K_print          : [expr_count = 1] [redir_type = ""]

[     2:0x7f8d697fefa0] Op_push             : sudo
[     2:0x7f8d697fefc0] Op_push             : kill
[     2:0x7f8d697ff040] Op_push             : STOP
[     2:0x7f8d697ff000] Op_minus            : 
[      :0x7f8d697ff080] Op_no_op            : 
[     2:0x7f8d697ff020] Op_push_i           : 2 [PERM|NUMCUR|NUMBER]
[     2:0x7f8d697ff060] Op_field_spec       : 
[      :0x7f8d697ff0c0] Op_concat           : [expr_count = 3] [concat_flag = 0]
[      :0x7f8d697ff0a0] Op_pop              : 
[      :0x7f8d697fee80] Op_no_op            : 
[      :0x7f8d697fef00] Op_atexit           : 
[      :0x7f8d697fefe0] Op_stop             : 
Program exited normally with exit value: 0

Pay attention at Op_no_op byte-code.

For run external command from awk, you can use awk system() function:

awk '{print $2;system("sudo kill -STOP " $2)}'
0

I know your question is about the difference in both the commands you had tried, but if you are not insistent about using awk, and for the benefit of anyone else who may stumble upon this post, another method would be to use pgrep -f.

kill $(pgrep -f wget)

This will kill all the process that is using wget. Use the signal that you wish to use with kill (if any).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.