mata vários processos usando ferramentas awk

1

Eu quero parar vários processos usando o awk. Meu comando é assim:

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

Eu quero parar todos os processos que estão executando o wget. $ 2 de awk significa o pid de cada processo.Mas eu acho que não funciona.O estado do processo permanece o mesmo.Eles ainda estão em execução.

Em vez disso, modifiquei este comando:

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

funciona! Então, alguém pode me dizer a diferença deles?

    
por wuchang 12.12.2014 / 04:17

3 respostas

4

Há muito a melhorar sobre sua abordagem:

  1. Na maioria dos sistemas (se /proc não estiver montado com hidepid ), você não precisa do privilégio root para ps .

  2. Não há necessidade de duas instâncias grep apenas para se livrar da primeira na lista de processos. Em vez disso, faça isso: grep '[w]get'

  3. Não há uso na entrada de filtragem grep para awk . awk pode fazer isso muito bem: awk '/wget/ {print $2}' (ou, devido ao ps problema: awk '/[w]get/ {print $2}' )

  4. Em vez de filtrar ps output e piping PIDs para kill , você poderia usar apenas killall wget

  5. Você chamaria sudo uma vez por awk e não uma vez por linha de entrada.

O principal problema em seu primeiro pipeline é o comando awk : awk '{print $2;sudo kill -STOP $2}' . Você pode executar comandos externos a partir de awk , mas não dessa maneira. Você precisa desta função awk : system(cmd-line)

Se você quiser usar ps e kill , faça desta maneira:

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

Para melhorias, consulte a resposta do @Hauke Laging .

Para a diferença entre a sua solução, a primeira abordagem não executa o comando kill , apenas se refere a quatro variáveis sudo , kill , STOP e $2 .

Pelo menos em gawk , quando você se refere a variáveis sem ação em uma instrução, não faz nada. Você pode facilmente usar dgawk para ver isso:

$ 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

Preste atenção em Op_no_op byte-code.

Para executar o comando externo de awk , você pode usar awk system () função:

awk '{print $2;system("sudo kill -STOP " $2)}'
    
por 12.12.2014 / 04:54
0

Sei que sua pergunta é sobre a diferença em ambos os comandos que você tentou, mas se você não insistir em usar awk e em benefício de qualquer outra pessoa que possa se deparar com esse post, outro método seria use pgrep -f .

kill $(pgrep -f wget)

Isso eliminará todo o processo que está usando wget . Use o sinal que você deseja usar com kill (se houver).

    
por 12.12.2014 / 05:25

Tags