Como posso evitar que o 'grep' apareça nos resultados ps?

266

Quando procuro um processo que não existe, por exemplo

$ ps aux | grep fnord                          
wayne    15745  0.0  0.0  13580   928 pts/6    S+   03:58   0:00 grep fnord

Obviamente, não me importo com o grep - isso faz tanto sentido quanto procurar pelo processo ps !

Como posso evitar que o grep apareça nos resultados?

    
por Wayne Werner 30.04.2013 / 15:44

14 respostas

379

Acontece que há uma solução encontrada no keychain .

$ ps aux | grep "[f]nord"

Colocando os colchetes ao redor da letra e aspas ao redor da string, você procura pelo regex, que diz: "Encontre o caractere 'f' seguido por 'nord'."

Mas desde que você coloque os colchetes no padrão, 'f' agora é seguido por ']', então grep não aparecerá na lista de resultados. Neato!

    
por 30.04.2013 / 15:44
152

Outra opção que uso (especialmente apenas para verificar se um processo está sendo executado) é a pgrep comando. Isso irá procurar por um processo de correspondência, mas não listará uma linha grep para a pesquisa. Eu gosto porque é uma maneira rápida de pesquisar, sem regexar ou escapar de nada.

pgrep fnord
    
por 30.04.2013 / 16:06
55

A solução ideal é aquela apresentada por BriGuy

pgrep fnord 

Mas se você não quer fazer isso, você pode simplesmente excluir todas as linhas que combinam com o grep com:

ps aux | grep -v grep | grep "fnord"
    
por 30.04.2013 / 17:07
19

Não é a solução mais elegante, mas você pode fazer isso:

$ ps aux | grep fnord | grep -v grep

    
por 30.04.2013 / 16:05
15

Em zsh, grep fnord =(ps aux) .

A ideia é, primeiro executar ps aux , colocar o resultado em um arquivo e usar grep nesse arquivo. Só que não temos um arquivo, pois usamos a "substituição de processo" do zsh.

Para ilustrar, tente

ps aux > ps.txt
grep fnord ps.txt
rm ps.txt

O resultado deve ser o mesmo.

Comentário geral sobre algumas das outras respostas. Alguns são muito complicados e / ou longos para digitar. Não é apenas uma questão de estar certo, deve ser utilizável também. Mas isso não significa que algumas dessas soluções sejam ruins; apenas, eles devem ser agrupados em uma mini-UI para torná-los utilizáveis.

    
por 01.05.2013 / 00:46
7
ps aux | grep $(echo fnord | sed "s/^\(.\)/[]/g")
    
por 30.04.2013 / 15:59
6

This answer is GNU-specific. See Wayne's answer for a more general solution.

Procurando por processos

Se você está apenas procurando fnord process, você pode usar a opção -C para selecionar pelo nome do comando:

ps -C fnord

Isto pode ser misturado com opções de formato no estilo BSD e POSIX ao seu gosto. Veja a página de manual ps para uma lista completa.

Procurando por mais alguma coisa?

Se você precisar de algo mais avançado do que uma busca exata por um nome de comando, não perca a esperança! Isso ainda pode ser feito no lado ps do pipe. Tudo o que precisamos fazer é informar ps para excluir grep process do resultado:

ps -NC grep | grep 'fnord'

-C grep seleciona todos os processos do grep e -N nega a seleção. Isso pode ser usado para procurar argumentos de comando, parte de um nome de comando ou expressões regulares mais complexas.

    
por 30.08.2016 / 19:34
3

Minha resposta é uma variação da resposta típica para procurar por "foobar" em uma listagem 'ps'. O argumento de "-A" "ps" é mais portátil que "aux", acredito, mas essa mudança é irrelevante para a resposta. A resposta típica é assim:

$ ps -A -ww | grep [f]oobar

Em vez disso, uso esse padrão:

$ ps -A -ww | grep [^]]foobar

A principal vantagem é que é mais fácil escrever scripts baseados nesses padrões, porque você simplesmente concatena uma string estática "[^]]" com qualquer padrão que esteja procurando. Você não precisa retirar a primeira letra da corda, em seguida, inseri-la entre as chaves quadradas e depois concatená-la novamente. Ao fazer o script no shell, é mais fácil simplesmente colocar "[^]]" na frente do padrão que você estava procurando. String fatiar em Bash é uma coisa feia, então minha variação evita isso. Esta variação diz mostrar as linhas onde o padrão corresponde SEM um colchete direito à direita]. Como o padrão de pesquisa para excluir um colchete na verdade adiciona o colchete ao padrão, ele nunca se igualará.

Então você pode escrever um comando portátil 'psgrep' como segue. Aqui, eu faço algumas diferenças entre o Linux, OS X BSD e outros. Isso adiciona os cabeçalhos de coluna de 'ps', fornece um formato 'ps' mais personalizado que atende às minhas necessidades, e exibe processos listando extra, extra wide para que nenhum dos argumentos da linha de comando seja perdido. Bem, a maioria não é perdida. Java sendo Java, muitas vezes faz as coisas da pior maneira possível, assim você alguns serviços java serão executados após o comprimento máximo permitido de argumentos que a tabela de processos acompanhará. Eu acredito que isso é 1024 caracteres. O comprimento de comando solitário permitido para iniciar um processo é muito maior, mas a tabela de processo do kernel não se preocupa em rastrear qualquer coisa com mais de 1K de comprimento. Uma vez que o comando é iniciado, o nome do comando e a lista de argumentos não são necessários, então o que é armazenado na tabela de processos é apenas informativo.

psgrep ()
{
    pattern=[^]]${1};
    case "$(uname -s)" in
        Darwin)
            ps -A -ww -o pid,ppid,nice,pri,pcpu,pmem,etime,user,wchan,stat,command | grep -i -e "^[[:space:]]*PID" -e ${pattern}
        ;;
        Linux)
            ps -A -ww -o pid,ppid,tid,nice,pri,pcpu,pmem,etime,user,wchan:20,stat,command | grep -i -e "^[[:space:]]*PID" -e ${pattern}
        ;;
        *)  # other UNIX flavors get a minimalist version.
            ps -A -ww | grep -i -e ${pattern}
        ;;
    esac
}
    
por 05.03.2016 / 02:46
2

A maneira mais simples de fazer agulhas para fazer isso seria armazená-lo em uma variável primeiro:

PS_OUTPUT="$(ps aux)"; echo "$PS_OUTPUT" |grep fnord

Chamada: @ EmanuelBerg grep fnord =(ps aux) a resposta é de longe a mais elegante, embora exija zsh . Eu tive brevemente em meus arquivos rc, mas bash reclama sobre essa sintaxe, mesmo apesar de uma condição que deve impedir a sua avaliação.

Dos meus arquivos rc, eu tenho uma versão sem distinção entre maiúsculas e minúsculas que pega args do grep:

psl() {
  local PS_OUTPUT="$(ps auxww)"
  echo "${PS_OUTPUT%%$'\n'*}" >&2  # title, in stderr to avoid pipes
  echo "${PS_OUTPUT#*$'\n'}" |grep -i "${@:-^}"
}

Code walk, um marcador por linha de código:

  • Capture a saída ps detalhada (em uma variável local para que desapareça quando a função retornar)
  • Exibe a primeira linha (o título) em erro padrão para que os resultados possam ser filtrados ainda sem afetar o título. A substituição diz: pegue $PS_OUTPUT e remova tudo após o primeiro feed de linha (regex equiv: s/\n.*$//msg ). Isso nos impede de usar o título
  • Exibir a saída ps com tudo exceto a primeira linha (regex equiv: s/^.*\n//m ) e grep seu conteúdo com -i para não diferenciar maiúsculas de minúsculas e com todos os argumentos entregues função (no caso de nenhum argumento, ^ , que corresponde ao início de qualquer linha para corresponder a tudo)
por 10.01.2015 / 04:12
1

Talvez seja hora de usar uma sequência real dessa vez. O uso de tubos torna paralelo.

ps aux >f && grep tmpfs <f

Feio porque haverá um arquivo f , mas não é minha culpa que não haja sintaxe para processos sequenciais onde você ainda quer usar a saída de um processo executado anteriormente.

Sugestão para a sintaxe de um operador sequencial:

ps aux ||| grep tmpfs
    
por 01.05.2013 / 16:59
0

O comando pgrep, como outros afirmaram, retornará o PID (ID do processo) dos processos com base no nome e em outros atributos. Por exemplo,

pgrep -d, -u <username> <string>

dará a você os PIDs, delimitados por uma vírgula (,) de todos os processos cujo nome corresponde à execução do usuário <username> . Você pode usar o comutador -x antes para retornar apenas correspondências exatas.

Se você quiser obter mais informações sobre esses processos (como a execução das opções de aux de ps implica), você pode usar a opção -p com ps, que corresponde com base no PID. Então, por exemplo,

ps up $(pgrep -d, -u <username> <string>)

fornecerá informações detalhadas de todos os PIDs correspondidos pelo comando pgrep.

    
por 14.05.2013 / 04:21
0

Aqui está um exemplo simples para encontrar o PID de ssh-agent para o nome de usuário sem mostrar o PID do processo grep :

ps xu | grep "${USER}.*[ ]/usr/bin/ssh-agent" | awk '{print $1 $2;}'

Se você quiser, por exemplo, matar ssh-agent para o usuário atual, use o seguinte comando:

kill 'ps xu | grep "${USER}.*[ ]/usr/bin/ssh-agent" | awk '{print $2;}''

Para criar um alias útil, adicione ao seu arquivo ~ / .bashrc ou ~ / .zshrc o seguinte código:

function function1 () {
    ps xu | grep "$1.*$2" | awk '{print $1" "$2" "$11;}'
}
alias mygrep="function1"

E para usar o alias aqui, há exemplos para forçar todos a aprender expressões regulares:

. /etc/profile #to make alias usable
mygrep ${USER} ${PROCESS_PATH}
mygrep ${USER} "[f]nord"
mygrep "[f]nord"
mygrep ".*[s]shd"

P.S. Eu só testei esses comandos no Ubuntu e no Gentoo.

    
por 06.11.2015 / 14:47
0

Usando a opção -x (correspondência exata) funcionou para mim. Eu combinei com -f (linha de comando completa), então eu poderia combinar meu processo precisamente com:

pgrep -x -f "path_i_used_when_starting/cmd params_i_used"
    
por 22.05.2017 / 00:21
-1

Você pode fazer isso facilmente, apenas com a definição de um ALIAS no seu .bashrc assim:

alias grep='grep -v grep | grep'
    
por 15.09.2015 / 15:26

Tags