Wie kann verhindert werden, dass "ps" seinen eigenen Prozess meldet?

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

Gibt es eine Möglichkeit zu verhindern, dass der letzte Prozess (d. H. Das Grep, das gleichzeitig mit meinem ps-Befehl gestartet wurde) gemeldet wird?

(Ich fing an zu versuchen, einen Regex zu finden, der mit dem Wortlaut übereinstimmt, aber nicht mit sich selbst übereinstimmt, aber das schien nicht der richtige Ansatz zu sein ...)

Steve Bennett
quelle

Antworten:

14

Meine Antwort ist eine Variation der typischen Antwort für die Suche nach "foobar" in einer psAuflistung. Das Argument von "-A" "ps"ist tragbarer als "aux", glaube ich, aber diese Änderung ist für die Antwort irrelevant. Die typische Antwort sieht so aus:

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

Stattdessen benutze ich dieses Muster:

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

Der Hauptvorteil ist, dass es einfacher ist, Skripte basierend auf diesen Mustern zu schreiben, da Sie einfach einen statischen String [^]]mit dem Muster verketten , nach dem Sie suchen. Sie müssen den ersten Buchstaben der Zeichenfolge nicht abstreifen, ihn dann zwischen die eckigen Klammern einfügen und ihn dann wieder zusammenfügen. Wenn [^]]Sie Skripte in der Shell schreiben, ist es einfacher, einfach vor dem Muster zu bleiben, nach dem Sie gesucht haben. Das Aufschneiden von Saiten in Bash ist eine hässliche Sache, also vermeidet meine Variante das. Diese Variante besagt, dass die Linien angezeigt werden, in denen das Muster OHNE führende eckige Klammer stimmt. Da das Suchmuster zum Ausschließen einer eckigen Klammer tatsächlich die eckige Klammer zum Muster hinzufügt, entspricht es sich selbst nie.

Sie könnten also einen portablen psgrepBefehl wie folgt schreiben . Hier berücksichtige ich einige Unterschiede zwischen Linux, OS X BSD und anderen. Dies fügt die Spaltenüberschriften aus ps, bietet eine benutzerdefiniertepsDas Format, das meinen Anforderungen entspricht, ist besser geeignet und zeigt Prozesse an, in denen eine zusätzliche, besonders breite Liste aufgeführt ist, sodass keines der Befehlszeilenargumente übersehen wird. Nun, die meisten werden nicht vermisst. Da Java Java ist, werden die Dinge oft auf die schlimmste Art und Weise ausgeführt, sodass einige Java-Services über die maximal zulässige Länge von Argumenten ausgeführt werden, die in der Prozesstabelle aufgezeichnet werden. Ich glaube das sind 1024 Zeichen. Die befehlsübergreifende Länge, die zum Starten eines Prozesses zulässig ist, ist viel länger, aber die Kernel-Prozesstabelle kümmert sich nicht darum, etwas über 1 KB Länge zu verfolgen. Sobald der Befehl gestartet ist, werden der Befehlsname und die Argumentliste nicht mehr benötigt. Was also in der Prozesstabelle gespeichert wird, dient nur der Information.

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
}
Noah Spurrier
quelle
Nachteil ist, dass dies tatsächlich ein Zeichen mehr (vor) als das ursprüngliche Muster entspricht. Zum Beispiel wird dies niemals mit der PID übereinstimmen. Und kann bei der Verwendung mit etwas irreführend sein grep --colour.
Tonin
67

+1 für @jamzed knappe Antwort, jedoch muss das OP möglicherweise erklärt werden:

ps | grep "[d]jango"

Mit diesem regulären Ausdruck starten Sie einen Prozess, dessen ps-Zeichenfolge nicht mit sich selbst übereinstimmt, da der reguläre Ausdruck übereinstimmt "django"und nicht "[d]jango". Auf diese Weise schließen Sie den Prozess mit der Zeichenfolge "[d] jango" aus, in diesem Fall grep. Dasselbe gilt für pgrep, egrep, awk, sed usw., je nachdem, mit welchem ​​Befehl Sie die Regex definiert haben.

Von Mann 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.
hmontoliu
quelle
2
Cool. Ich bin eigentlich ziemlich vertraut mit regulären Ausdrücken, aber ich konnte mir keine Möglichkeit vorstellen, um zu verhindern, dass der reguläre Ausdruck sich selbst anpasst. Das Einschließen eines Buchstabens in eckige Klammern ist absolut sinnvoll. (Einschließlich etwas wie [^!] Würde auch funktionieren ...)
Steve Bennett
1
Das ist schön und schlau.
Asche
Für den speziellen Fall 'ps' verwende ich '[]' vor dem Prozessnamen, nach dem ich suche. Dann muss ich den Prozessnamen nicht speziell für den regulären Ausdruck analysieren, aber er stimmt trotzdem überein.
Neromancer
@hmontoliu Es ist zum Beispiel nicht arbeiten: ps aux | grep [s]cript1. Können Sie uns helfen, die Lösung zu kommentieren?
SOUser
@ Montoliu Meine Schuld. Es scheint, dass die Zeile wegen der vorherigen Suchen
angezeigt wird
30

ps | grep [d]jango

ps | grep d[j]ango

...

ps | grep djang[o]

jamzed
quelle
Fügen Sie Leerzeichen hinzu, wenn Sie ein Zeichen benötigen:ps aux| grep "[Z] "
AD
@ Jamzed Es funktioniert nicht zum Beispiel: ps aux | grep [s]cript1oder ps aux | grep [s]cript2. Die grep-Linie wird weiterhin angezeigt. Können Sie uns helfen, die Lösung zu kommentieren?
SOUser
@ Jamzed Meine Schuld. Es scheint, dass die Zeile wegen der vorherigen Suchen
angezeigt wird
18

Verwenden Sie stattdessen pgrep: pgrep -lf django

Ramruma
quelle
Wie immer habe ich vergessen, die Plattform zu erwähnen (in diesem Fall OS X). Vermutlich funktioniert pgrep unter verschiedenen Linux-Betriebssystemen.
Steve Bennett
Ich stimme nicht zu, @ Ramruma. Ich bin genau zu diesem Thread gekommen, weil pgrepes mir genau dieses Problem gibt. Aber ich muss sagen, dass ich es in CygWin teste (wo psnicht die vollständige Befehlszeile des Prozesses angezeigt werden kann).
Sopalajo de Arrierez
Im Handbuch heißt es: "Der ausgeführte pgrep- oder pkill-Prozess meldet sich niemals als Übereinstimmung."
DeltaB
Ich habe mich gerade mit einem Problem befasst, von dem ich dachte, dass pgrepes zu mir passt. Es stellte sich heraus, dass es mit dem Namen der bashSkriptdatei übereinstimmte, von der aus ich es ausgeführt habe. Durch Hinzufügen von -xfixed it wird eine exakte Übereinstimmung mit dem Befehlsnamen hergestellt.
Andynormancx
11

Oh warte, das funktioniert:

ps | grep django | grep -v grep
Steve Bennett
quelle
7
Nur wenn die Prozessbefehlszeile nicht legitimerweise enthält grep, worauf Sie im allgemeinen Fall nicht zählen können.
ein CVn
8

ps -d | grep django

von mann ps:

 -d                  Lists information  about  all  processes
                     except session leaders.
bla
quelle
zeigt immer noch grep auf meine ...
Kevin
Ja, das funktioniert für mich unter OS X.
Steve Bennett
Funktioniert unter Linux nicht so gut.
Acumenus
Im Allgemeinen sind die Optionen psnotorisch nicht portierbar. Ohne Informationen darüber, für welche Plattform dies ist, ist diese Antwort nicht sehr hilfreich. Darüber hinaus ist dies offensichtlich nicht ausreichend, wenn Sie nicht sicher sind, ob der gesuchte Prozess kein Prozessleiter ist (dh dies kann hilfreich sein, wenn Ihr Ziel ein Daemon ist, aber nicht generell anders).
Tripleee
Komisch, auf dem Mac scheint dies nur den Grep-Prozess zu zeigen und alles andere herauszufiltern.
Christopher Hunter