ps aux | grep com um ponto

4

Estou tentando escrever um script que atenda a um processo em execução.

Estou tentando evitar que o grep real retorne da saída ps aux .

No entanto, estou obtendo resultados variados se usar um ponto ou não:

ps aux | grep [s]elenium não retorna nada.

ps aux | grep [s]elenium.jar retorna o comando grep:

beebee   36155  0.0  0.0  15940   956 pts/0    S+   16:20   0:00 grep --color=auto selenium.jar

Por que isso?

    
por Beebee 15.06.2016 / 17:24

3 respostas

12

Eu acho que você tem um arquivo chamado selenium.jar , mas nenhum arquivo chamado selenium na sua pasta atual.

Se você correr

 ps aux | grep [s]elenium.jar

o shell tentará substituir [s]elenium.jar pelos nomes dos arquivos correspondentes da pasta atual. Se houver um arquivo chamado selenium.jar que corresponderá e [s]elenium.jar será substituído por selenium.jar .

O shell executará o comando com o valor substituído, ou seja,

ps aux | grep selenium.jar

Para evitar essa citação, use o regex para protegê-lo do shell:

ps aux | grep '[s]elenium.jar'
    
por Florian Diesch 15.06.2016 / 17:35
5

O problema aqui, como @Florian percebe descoberto , é que o shell está expandindo os caracteres glob na sua pesquisa string para um nome de arquivo correspondente antes de passar a string para grep .

A execução de ps aux | grep foo é problemática, pois o comando grep foo corresponderá a foo e aparecerá na saída. Há duas soluções comuns, se complicadas, para isso. Você pode adicionar um grep -v grep no final do canal ou usar grep [f]oo . Como grep funciona com expressões regulares, ele tratará [f] como "qualquer caractere na lista de caracteres dentro dos colchetes". Como o único caractere entre colchetes é f , [f]oo é equivalente a foo . No entanto, o processo grep exibido nos resultados ps terá a string [f]oo e, portanto, não será encontrado por grep .

Isso se torna mais complicado se, como parece ser o caso para você, você tem um arquivo chamado foo em seu diretório atual. Como você não citou a expressão que deu a grep (porque usou [s]elenium e não '[s]elenium' ou "[s]elenium" ), o shell tratará como glob e expandi-lo para o nome do arquivo correspondente. Isso renderiza o [s]elenium como inútil, já que o que é realmente passado para grep é selenium e não [s]elenium , então o grep irá corresponder a si mesmo.

Tudo isso, no entanto, só acontece porque você não está usando a ferramenta certa para o trabalho. Como é frequentemente o caso, há um aplicativo para isso! Não use grep + ps . Em vez disso, use pgrep , que é projetado para fazer exatamente o que você deseja:

NAME
       pgrep,  pkill  -  look  up  or signal processes based on name and other
       attributes

SYNOPSIS
       pgrep [options] pattern
       pkill [options] pattern

DESCRIPTION
       pgrep looks through the  currently  running  processes  and  lists  the
       process IDs which match the selection criteria to stdout.  All the cri‐
       teria have to match.  For example,

         $ pgrep -u root sshd

Então, no seu caso, você pode apenas fazer

pgrep selenium

Ou, como você está usando o java , use -f , que pesquisa toda a linha de comando:

pgrep -f selenium
    
por terdon 15.06.2016 / 18:28
1

Você pode excluir o "grep" após o inicial grep:

ps aux | grep '[s]elenium.jar' | grep -v grep
    
por drew 15.06.2016 / 17:30