Como evitar que "ps" relate seu próprio processo?


52
$ ps | grep django
28006 ttys004    0:01.12 /usr/bin/python bin/django celeryd --beat
51393 ttys005    0:01.45 /usr/bin/python bin/django celeryd -l INFO
51472 ttys005    0:01.29 /usr/bin/python bin/django celeryd -l INFO
51510 ttys005    0:01.89 /usr/bin/python bin/django celeryd -l INFO
51801 ttys005    0:01.83 /usr/bin/python bin/django celeryd -l INFO
53470 ttys005    0:03.97 /usr/bin/python bin/django celeryd -l INFO
53780 ttys005    0:00.00 grep django

Existe uma maneira de impedir que o último processo (ou seja, o grep iniciado ao mesmo tempo que o meu comando ps) seja relatado?

(Comecei a tentar criar uma regex que correspondesse ao literal, mas não ao próprio, mas que parecia, hum, não a abordagem correta ...)

Respostas:


14

Minha resposta é uma variação da resposta típica para procurar "foobar" em uma pslistagem. O argumento de "-A" "ps"é mais portátil do 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 este padrão:

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

A principal vantagem é que é mais fácil escrever scripts com base nesses padrões, porque você simplesmente concatena uma sequência estática [^]]com qualquer padrão que esteja procurando. Você não precisa retirar a primeira letra da string, depois inseri-la entre os colchetes e concatenar isso novamente. Ao criar scripts no shell, é mais fácil ficar [^]]na frente do padrão que você estava procurando. Fatiar cordas no Bash é uma coisa feia, então minha variação evita isso. Essa variação indica as linhas em que o padrão corresponde SEM um colchete quadrado à direita]. Como o padrão de pesquisa para excluir um colchete, na verdade, adiciona o colchete ao padrão, ele nunca será correspondido.

Então você pode escrever um psgrepcomando portátil da seguinte maneira. Aqui, considero algumas diferenças entre Linux, OS X BSD e outros. Isso adiciona os cabeçalhos das colunas ps, fornece uma configuração mais personalizadapsformato que melhor se adapte às minhas necessidades e exibe processos que listam extra, extra largo, para que nenhum dos argumentos da linha de comando seja esquecido. Bem, a maioria não faz falta. Java sendo Java, geralmente faz as coisas da pior maneira possível; portanto, alguns serviços java executam o comprimento máximo permitido de argumentos que a tabela de processos acompanhará. Acredito que sejam 1024 caracteres. O tamanho do comando único que é permitido iniciar um processo é muito mais longo, mas a tabela de processos do kernel não se preocupa em rastrear algo com mais de 1K de comprimento. Depois que o comando é iniciado, a lista de argumentos e nomes de comandos não é necessária; portanto, 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
}

A desvantagem é que isso realmente corresponderá a um caractere a mais (na frente) do que o padrão original. Por exemplo, isso nunca corresponderá ao PID. E pode ser um pouco enganador quando usado com grep --colour.
— Tonin

67

+1 para resposta concisa @jamzed, no entanto, o OP pode precisar de alguma explicação:

ps | grep "[d]jango"

Usando esse regex, você está iniciando um processo cuja sequência ps não corresponderá a si própria, uma vez que o regexp corresponde "django"e não "[d]jango". Dessa forma, você excluirá o processo que possui a string "[d] jango", que neste caso é grep; O mesmo pode ser aplicado ao pgrep, egrep, awk, sed, etc ... qualquer que seja o comando usado para definir o regex.

Do homem 7 regex

   A bracket expression is a list of characters enclosed in "[]".  It nor‐
   mally matches any single character from the list (but see  below).   If
   the  list  begins  with  '^',  it matches any single character (but see
   below) not from the rest of the list.  If two characters  in  the  list
   are  separated  by '-', this is shorthand for the full range of charac‐
   ters between those two (inclusive) in the collating sequence, for exam‐
   ple,  "[0-9]" in ASCII matches any decimal digit.  It is illegal(!) for
   two ranges to share an endpoint, for example, "a-c-e".  Ranges are very
   collating-sequence-dependent,  and portable programs should avoid rely‐
   ing on them.

2
Legal. Na verdade, estou bastante confortável com regexs, mas não consegui pensar imediatamente em uma maneira de impedir que o regexp se correspondesse. Colocar uma carta entre colchetes faz todo o sentido. (Incluindo algo como [^!] Também funcionaria ...)
— Steve Bennett

11
Isso é legal e astuto.
— cinzas

Para o caso específico de 'ps', uso '[]' na frente do nome do processo que estou procurando. Então não preciso analisar o nome do processo especialmente para a regex, mas ainda corresponde.
— Neromancer

@hmontoliu Ele não funciona, por exemplo: ps aux | grep [s]cript1. Você poderia ajudar a comentar sobre a solução?
— SOUser

@hmontoliu A culpa é minha. Parece que a linha é mostrada por causa das pesquisas anteriores ...
— SOUser

30

ps | grep [d]jango

ps | grep d[j]ango

...

ps | grep djang[o]


Adicione espaço se você precisar grep um caractere:ps aux| grep "[Z] "
— 5/06/15 AD

@jamzed Não funciona, por exemplo: ps aux | grep [s]cript1ou ps aux | grep [s]cript2. A linha grep ainda é mostrada. Você poderia ajudar a comentar sobre a solução?
— SOUser

@jamzed Minha culpa. Parece que a linha é mostrada por causa das pesquisas anteriores ...
— SOUser

18

Use pgrep: pgrep -lf django


Como sempre, eu esqueci de mencionar a plataforma (OS X neste caso). Presumivelmente, o pgrep funciona em vários linuxes.
— Steve Bennett

Eu não concordo, @ramruma. Eu vim para este segmento precisamente porque pgrepme dá exatamente esse problema. Mas devo dizer que estou testando no CygWin (onde psnão é possível mostrar a linha de comando completa do processo).
— Sopalajo de Arrierez 04/04

O manual declara "O processo em execução pgrep ou pkill nunca se reportará como uma correspondência." E, na verdade, eu não o vi fazer isso.
— Deltab # 7/16

Acabei de lidar com um problema em que pensei que pgrepestava se combinando. Acontece que ele estava correspondendo ao nome do basharquivo de script do qual estava sendo executado. Adicionando -xcorrigido, então ele faz uma correspondência exata no nome do comando.
— andynormancx 14/03

11

Oh espera, isso funciona:

ps | grep django | grep -v grep

7
Somente se a linha de comando do processo não incluir legitimamente grep, com a qual você não pode contar no caso geral.
— a CVn

8

ps -d | grep django

do homem ps:

 -d                  Lists information  about  all  processes
                     except session leaders.

mostra ainda grep na minha ...
— Kevin

Sim, isso funciona para mim no OS X.
— Steve Bennett

Não funciona tão bem no Linux.
— Acumenus 18/08/14

De um modo mais geral, as opções pssão notoriamente não portáveis; portanto, sem informações sobre qual plataforma é, essa resposta não é muito útil. Além disso, isso obviamente não é adequado quando você não tem certeza de que o processo que você está procurando não é um líder de processo (ou seja, isso pode ajudar se seu destino for um daemon, mas geralmente não o contrário).
— Tripleee

Engraçado, no Mac, isso parece mostrar apenas o processo grep e filtra todo o resto.
— Christopher Hunter
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.