ps | grep mostra resultados ruins em subshell com jobs rodando em segundo plano

1

Estou usando o bash. Eu tenho um arquivo chamado "a2draw" que contém apenas uma linha:

sleep 99999

Eu inicio usando este comando:

bash a2draw &

Agora, eu sei e entendo o truque com colchetes que permite omitir o processo do grep na saída do ps:

ps aux | grep cron
root      1079  0.0  0.0   2596   788 ?        Ss   Mar25   0:00 cron
root      1119  0.0  0.0   3684   696 ?        Ss   Mar25   0:00 /usr/sbin/incrond -f /etc/incron.conf
ja       29781  0.0  0.0   4368   820 pts/10   S+   12:49   0:00 grep cron

ps aux | grep [c]ron
root      1079  0.0  0.0   2596   788 ?        Ss   Mar25   0:00 cron
root      1119  0.0  0.0   3684   696 ?        Ss   Mar25   0:00 /usr/sbin/incrond -f /etc/incron.conf

Mas, de alguma forma, não funciona no subshell que tem trabalhos em segundo plano:

jobs
[1]+  Running                 bash a2draw &

ps aux | grep [a]2draw
ja       22977  0.0  0.0   5172  1080 pts/10   S    12:21   0:00 bash a2draw
ja       30242  0.0  0.0   4364   816 pts/10   R+   12:50   0:00 grep

O que é ainda mais estranho, descartar uma letra do nome do processo produz resultados corretos:

ps aux | grep [a]2dra
ja       22977  0.0  0.0   5172  1080 pts/10   S    12:21   0:00 bash a2draw

Em outro shell, tudo funciona como eu esperava:

ps aux | grep [a]2draw
ja       22977  0.0  0.0   5172  1080 pts/10   S    12:21   0:00 bash a2draw

ps aux | grep [a]2dra
ja       22977  0.0  0.0   5172  1080 pts/10   S    12:21   0:00 bash a2draw

Eu não sei o que está acontecendo. Existe algo especial sobre trabalhos em segundo plano que modifiquem como a criação de tubulações funciona?

    
por user1042840 27.03.2013 / 13:11

1 resposta

2

Se você tivesse usado zsh ou (t)csh em vez de bash , teria entendido seu erro:

$ ps -ef | grep [c]ron
zsh: no matches found: [c]ron

Acima, você tem um padrão globbing que deve ser expandido para a lista de arquivos no diretório atual que corresponde a esse padrão.

Na maioria dos shells parecidos com Bourne e rc, no entanto, se não houver nenhum arquivo correspondente, o padrão é silenciosamente passado intocado para o comando.

É por isso que funciona com [c]ron , porque não há nenhum arquivo chamado cron no diretório atual, mas não com [a]2draw , porque há um arquivo correspondente a esse padrão no diretório atual, ele é expandido por o shell para a2draw e grep obtém um argumento a2draw em vez de [a]2draw .

Observe que bash pode ser configurado para funcionar como zsh , nesse caso:

shopt -s failglob

O shell fish também relata um erro quando um glob não corresponde. No entanto, [...] não é um operador globbing em fish .

O que isso significa é que você precisa citar os caracteres globbing quando não pretende que sejam expandidos:

ps -ef | grep '[a]2draw'

Você pode sair sem fazer isso em bash ou outros shells parecidos com Bourne, exceto zsh , mas isso faz com que bugs inativos estejam prontos para serem acionados no dia em que você executar o comando em um diretório que tenha um arquivo correspondente.

Eu posso ter efeitos colaterais desagradáveis, como em contextos insuspeitados. Como:

rm -?

Em um diretório que tenha arquivos chamados -- , -x e -y removerá os dois -x e -y .

    
por 27.03.2013 / 13:41

Tags