Esse é um comportamento perfeitamente esperado, mas talvez um pouco confuso se você não souber exatamente o que os comandos envolvidos realmente fazem. E não, não há softwares maliciosos envolvidos. Vou tentar explicar o que realmente está acontecendo aqui.
Primeiro, quando você executar ps ax
, isso fornecerá uma lista de todos os processos em execução no sistema e (alguns de) seus argumentos de linha de comando.
Em segundo lugar, quando você executar grep "nginx"
que lerá a partir de sua entrada padrão (porque você não forneceu um arquivo a ser usado como entrada) e exibirá quaisquer linhas que contenham a string nginx
.
No shell de um sistema semelhante ao Unix (como o Mac OS X), os canais geralmente são implementados de forma que, basicamente, os comandos são iniciados da direita para a esquerda, mas os dados são transportados de da esquerda para a direita.
Então, eis o que acontece: Primeiro grep
é iniciado, com o argumento nginx
. Segundo, ps
é iniciado com o argumento ax
e sua saída padrão é vinculada à entrada padrão do processo grep
. Como ps
é executado, sua saída é alimentada para a saída padrão de ps
, que é a mesma coisa que a entrada padrão de grep
. Por sua vez, grep
olha para cada linha, procurando pela string nginx
, porque foi isso que você disse a grep
para fazer. Tal linha aparece uma vez: o grep se processa com seus argumentos de linha de comando! Como resultado, esta linha é impressa por grep
para a saída padrão do grep , e todos outros são suprimidos. Em seu primeiro exemplo, a saída padrão do grep não está vinculada a nenhum outro processo, portanto, por padrão, ela é impressa no terminal. Quando não houver mais dados de ps
, então grep
também sairá porque todos os comandos estão interligados; Não faz qualquer sentido real ter um deles em execução quando outro terminou.
Quando você canaliza a saída do grep por meio de awk
para xargs kill
, o que acontece é que o xargs cria uma lista do que vai fazer, mas na verdade não o faz até o final. Então, no momento em que o xargs começa a invocar o kill, o processo do grep - que tinha o nginx entre seus parâmetros de linha de comando - já se foi. Portanto, não há processo para enviar um sinal para, e kill
avisa sobre esse fato.
Como você pode ver, não há nenhum processo nginx desonesto sendo executado em seu sistema evitando suas tentativas de encontrá-lo; existe apenas o grep, que é iniciado repetidamente, uma vez para cada vez que você olha, o que se encontra.
Você pode evitar isso usando grupos de caracteres em algum lugar da string de pesquisa, porque isso não ocorrerá. Por exemplo, ps ax | grep foobar
retorna o processo do grep, mas ps ax | grep 'fooba[r]'
não, porque fooba[r]
não é a mesma coisa que foobar
quando comparado como uma string simples. ( [r]
corresponde a qualquer um dos caracteres r
, portanto, apenas r
.) Observe que, para fazer isso, você provavelmente terá que escapar do argumento para grep
.
Como um aparte, é quase sempre desnecessário executar primeiro grep
e depois awk
sem nada mais. Em vez de ... | grep 'foobar' | awk '{ print $2 }'
para algum comando anterior ...
, você pode simplesmente usar ... | awk '/foobar/ { print $2 }'
para que o awk execute ambas as tarefas. Isso é mais comumente encontrado com cat
, onde é chamado Uso inútil do gato , mas o conceito também é generalizado para outros comandos, como o grep no seu caso.