O $2
está entre aspas duplas na linha de comando do shell local, então é expandido pelo seu shell local (provavelmente para a string vazia).
Portanto, o comando executado no host remoto é algo como:
ps -ef | grep foo | grep -v grep | awk {'print '} | xargs kill -9
Esse comando awk
não funciona (imprime todas as linhas) e xargs
será executado:
kill -9 <all-the-words-present-in-the-output-of-ps|grep...>
Isso inclui pid e ppid, nomes de usuários ...
Além disso, se o comando pid do kill estiver nessa lista, ele se matará e, portanto, não conseguirá matar os restantes na lista.
Aqui, você deseja:
ssh foo@<IP Address> 'pkill -KILL -f foo'
(mata todos os processos cuja linha de comando (pelo menos os primeiros kilobytes dele) contém foo
).
Ou se o sistema remoto não tiver o comando pkill
:
ssh foo@<IP Address> '
ps -eo pid= -o args= |
awk "/[f]oo/ {print \}" |
xargs kill -s KILL'
Usamos aspas simples no lado local (portanto, nenhuma expansão de variável lá) e aspas duplas para a linha de comando do shell remoto, portanto, precisamos escapar do $
in $1
para que ele não seja expandido pelo shell remoto.
awk
é um superconjunto de grep
, você geralmente não precisa juntá-los. O melhor é dizer a ps
para produzir apenas as coisas que você quer combinar, aqui assumindo que você quer procurar por foo
na lista de argumentos mostrada por ps como seu uso de -f
sugere.
Se você quiser matar todos os processos do usuário remoto (aqui do usuário foo e sshing como foo), você poderia fazer:
ssh foo@<IP Address> 'kill -s KILL -- -1'
Isso eliminará todos os processos que o usuário tem permissão para matar. Para um usuário normal, são todos os processos cujo ID de usuário definido real ou salvo é o mesmo que o ID de usuário real ou efetivo do processo de eliminação.
Ou:
ssh foo@<IP Address> 'pkill -KILL -U "$(id -u)"'
(ou pkill -U foo
). Para matar todos os processos cujo ID de usuário real é o mesmo que o ID de usuário efetivo do usuário remoto.
Ou você poderia fazer:
ssh foo@<IP Address> '
trap "" HUP
ps -eo sid= -o pid= -U "$(id -u)" |
awk "\ != $(ps -eo sid= -p "\$\$") {print \}" |
xargs kill -s KILL'
(verificando em sid
para que kill
não se mate, o shell, awk
ou xargs
e ignorando SIGHUP no caso de matar o usuário sshd
processo faz com que esse sinal seja enviado)
Estamos assumindo que o shell de login do usuário remoto é semelhante ao Bourne. Esses comandos teriam que ser adaptados se o shell de login do usuário remoto for das famílias csh ou rc que possuem uma sintaxe diferente, por exemplo.
Também é melhor referir-se aos sinais pelo nome em vez do número, o que torna mais claro e o número do sinal pode mudar de sistema para sistema (9 para o SIGKILL é bastante universal).