Come impedire a "ps" di segnalare il proprio 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

Esiste un modo per impedire che venga segnalato l'ultimo processo (ovvero il grep che è stato avviato contemporaneamente al mio comando ps)?

(Ho iniziato a provare a trovare una regex che corrispondesse al letterale ma non corrispondesse a se stessa, ma sembrava, um, non l'approccio giusto ...)

Risposte:


14

La mia risposta è una variazione della risposta tipica per la ricerca di "foobar" in un pselenco. L'argomento di "-A" "ps"è più portatile di "aux", credo, ma questo cambiamento è irrilevante per la risposta. La risposta tipica è questa:

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

Invece uso questo modello:

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

Il vantaggio principale è che è più semplice scrivere script basati su questi schemi perché concateni semplicemente una stringa statica [^]]con qualunque modello tu stia cercando. Non è necessario rimuovere la prima lettera della stringa, quindi inserirla tra le parentesi quadre e quindi concatenarla nuovamente insieme. Quando [^]]si esegue lo scripting in shell è più semplice restare semplicemente davanti allo schema che stavi cercando per cercare. Il taglio delle corde in Bash è una cosa brutta, quindi la mia variazione lo evita. Questa variazione dice mostra le linee in cui il modello corrisponde SENZA una parentesi quadra di destra]. Poiché il modello di ricerca per escludere una parentesi quadra aggiunge effettivamente la parentesi quadra al modello, allora non corrisponderà mai a se stesso.

Quindi potresti scrivere un psgrepcomando portatile come segue. Qui, tengo conto delle differenze tra Linux, OS X BSD e altri. Questo aggiunge le intestazioni di colonna da ps, fornisce una più personalizzatapsil formato adatto alle mie esigenze migliori e visualizza i processi che elencano extra, extra in modo che nessuno degli argomenti della riga di comando venga perso. Bene, molti non sono mancati. Essendo Java, spesso fa le cose nel modo peggiore possibile, quindi alcuni servizi Java correranno oltre la lunghezza massima consentita degli argomenti che la tabella dei processi terrà traccia. Credo che questo sia 1024 caratteri. La lunghezza della sola riga di comando consentita per avviare un processo è molto più lunga, ma la tabella dei processi del kernel non si preoccupa di tenere traccia di qualsiasi lunghezza superiore a 1 KB. Una volta avviato il comando, l'elenco dei nomi dei comandi e degli argomenti non è necessario, quindi ciò che viene memorizzato nella tabella dei processi è solo 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
}

Lo svantaggio è che questo corrisponderà effettivamente a un carattere in più (davanti) rispetto al modello originale. Ad esempio, questo non corrisponderà mai al PID. E può essere un po 'fuorviante se utilizzato con grep --colour.
Tonin,

67

+1 per la risposta concisa di @jamzed, tuttavia l'OP potrebbe aver bisogno di una spiegazione:

ps | grep "[d]jango"

Usando quel regex stai avviando un processo che la sua stringa ps non corrisponderà a se stessa, poiché il regexp corrisponde "django"e no "[d]jango". In questo modo escluderai il processo che ha la stringa "[d] jango" che in questo caso è grep; Lo stesso può essere applicato a pgrep, egrep, awk, sed, ecc ... qualunque comando tu abbia usato per definire il regex.

Da man 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
Freddo. In realtà sono abbastanza a mio agio con regexs, ma non sono riuscito a pensare immediatamente a un modo per impedire che regexp si abbinasse da solo. Racchiudere una lettera tra parentesi quadre ha perfettamente senso. (Includere qualcosa come [^!] Funzionerebbe anche ...)
Steve Bennett il

1
È carino e furbo.
ash

Per il caso specifico "ps", utilizzo "[]" all'inizio del nome del processo che sto cercando. Quindi non ho bisogno di analizzare il nome del processo appositamente per la regex, ma corrisponde ancora.
Neromante,

@hmontoliu Non funziona, per esempio: ps aux | grep [s]cript1. Potresti aiutare a commentare la soluzione?
SOUser,

@hmontoliu Colpa mia. Sembra che la linea sia mostrata a causa delle ricerche precedenti ...
SOUser

30

ps | grep [d]jango

ps | grep d[j]ango

...

ps | grep djang[o]


Aggiungi spazio se hai bisogno di grep un carattere:ps aux| grep "[Z] "
AD

@jamzed Non funziona per esempio: ps aux | grep [s]cript1o ps aux | grep [s]cript2. La linea grep è ancora mostrata. Potresti aiutare a commentare la soluzione?
SOUser,

@jamzed Colpa mia. Sembra che la linea sia mostrata a causa delle ricerche precedenti ...
SOUser

18

Usa invece pgrep: pgrep -lf django


Come al solito ho dimenticato di menzionare la piattaforma (OS X in questo caso). Presumibilmente pgrep funziona su vari Linux.
Steve Bennett,

Non sono d'accordo, @ramruma. Sono arrivato a questo thread proprio perché pgrepmi dà esattamente questo problema. Ma devo dire che lo sto testando in CygWin (dove psnon è possibile mostrare l'intera riga di comando del processo).
Sopalajo de Arrierez,

Il manuale afferma "L'esecuzione del processo pgrep o pkill non si riferirà mai come una corrispondenza", e in effetti non l'ho visto farlo.
Delta

Ho appena avuto a che fare con un problema in cui pensavo si pgrepstesse abbinando. Si scopre che corrispondeva al nome del bashfile di script da cui lo stavo eseguendo. L'aggiunta l'ha -xriparato, quindi fa una corrispondenza esatta sul nome del comando.
andynormancx

11

Oh aspetta, questo funziona:

ps | grep django | grep -v grep

7
Solo se la riga di comando del processo non include legittimamente grep, su cui non si può fare affidamento nel caso generale.
un CVn

8

ps -d | grep django

da man ps:

 -d                  Lists information  about  all  processes
                     except session leaders.

mostra ancora grep sul mio ...
Kevin

Sì, questo funziona per me su OS X.
Steve Bennett,

Non funziona così bene su Linux.
Acumenus,

Più in generale, le opzioni pssono notoriamente non portatili, quindi senza informazioni su quale piattaforma sia, questa risposta non è molto utile. Inoltre, questo ovviamente non è adeguato quando non si è certi che il processo che si sta cercando non sia un leader di processo (ciò può aiutare se il proprio target è un demone, ma in genere non altrimenti).
Tripleee

Divertente, su Mac questo sembra mostrare solo il processo grep e filtra tutto il resto.
Christopher Hunter,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.