我想使用 awk 停止多个进程。我的命令是这样的:
sudo ps -ef|grep wget |grep -v grep|awk '{print $2;sudo kill -STOP $2}'
我想停止所有正在运行 wget 的进程。 awk的$2表示每个进程的pid。但是我发现它不起作用。进程的状态保持不变。它们仍在运行。
相反,我修改了这个命令:
sudo ps -ef|grep wget |grep -v grep|awk '{print $2}'|xargs sudo kill -STOP
有用!那么,谁能告诉我它们的区别?
答案1
您的方法还有很多需要改进的地方:
在大多数系统上(如果
/proc
未安装hidepid
),您不需要root
的权限ps
。不需要两个
grep
实例来删除进程列表中的第一个实例。改为这样做:grep '[w]get'
grep
过滤输入是没有用的awk
。awk
可以自己很好地做到这一点:(awk '/wget/ {print $2}'
或者,由于ps
问题awk '/[w]get/ {print $2}'
:)您可以使用以下命令,而不是过滤输出
ps
并将 PID 传递给您kill
killall wget
您将针对每个输入行调用
sudo
一次而不是一次。awk
您的第一个管道中的主要问题是awk
命令:awk '{print $2;sudo kill -STOP $2}'
。您可以从运行外部命令,awk
但不能以这种方式运行。您需要此awk
功能:system(cmd-line)
如果你想使用ps
然后kill
这样做:
kill -STOP $(ps -ef | awk '/[w]get/ {print $2}')
答案2
我知道您的问题是关于您尝试过的两个命令的差异,但是如果您不坚持使用awk
,并且为了其他可能偶然发现这篇文章的人的利益,另一种方法是使用pgrep -f
。
kill $(pgrep -f wget)
这将杀死所有正在使用的进程wget
。使用您想要使用的信号kill
(如果有)。
答案3
如需改进,请参阅@Hauke Laging 的回答。
对于您的解决方案之间的差异,第一种方法不运行kill
命令,它只引用四个变量sudo
、kill
和。STOP
$2
至少在 中gawk
,当您在语句中引用没有操作的变量时,它不会执行任何操作。您可以轻松地使用dgawk
来查看:
$ 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
注意Op_no_op
字节码。
要从 运行外部命令awk
,您可以使用awk
系统()功能:
awk '{print $2;system("sudo kill -STOP " $2)}'