Frage Wie verhindert man, dass "ps" seinen eigenen Prozess meldet?


$ 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 (also der Grep, der zur gleichen Zeit wie mein PS-Befehl gestartet wurde) gemeldet wird?

(Ich begann zu versuchen, eine Regex zu entwickeln, die dem Literal entspricht, aber nicht mit sich selbst übereinstimmt, aber das schien ähm, nicht der richtige Ansatz ...)


49
2018-03-09 05:42


Ursprung




Antworten:


Meine Antwort ist eine Variation der typischen Antwort für die Suche nach "Foobar" in a ps Auflistung. 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 diesem Muster zu schreiben, da Sie einfach eine statische Zeichenfolge verketten [^]] mit welchem ​​Muster auch immer du suchst. Sie müssen den ersten Buchstaben der Zeichenfolge nicht abzustreifen, dann zwischen den quadratischen Klammern einfügen und dann die wieder zusammenfügen. Beim Scripting in der Shell ist es einfacher, einfach zu bleiben [^]] vor dem Muster, nach dem du gesucht hast. String Slicing in Bash ist eine hässliche Sache, so dass meine Variation das vermeidet. Diese Variation sagt, dass die Linien, wo das Muster OHNE eine führende rechte eckige Klammer entspricht, übereinstimmen. Da das Suchmuster zum Ausschließen einer eckigen Klammer tatsächlich die eckige Klammer zu dem Muster hinzufügt, wird es sich niemals selbst zuordnen.

So könnte man einen tragbaren schreiben psgrep Befehl wie folgt. Hier berücksichtige ich Unterschiede zwischen Linux, OS X BSD und anderen. Dies fügt die Spaltenüberschriften hinzu ps, bietet eine mehr benutzerdefinierte ps Das Format passt besser zu meinen Anforderungen und zeigt Prozesse, die extra, extra breit auflisten, so dass keines der Befehlszeilenargumente übersehen wird. Nun, die meisten werden nicht vermisst. Da Java Java ist, macht es oft Dinge auf die schlechteste Art und Weise, so dass einige Java-Dienste die maximal zulässige Länge von Argumenten überschreiten, die die Prozesstabelle verfolgen wird. Ich glaube, das sind 1024 Zeichen. Die Befehlslänge, die zum Starten eines Prozesses erlaubt ist, ist viel länger, aber die Kernel-Prozesstabelle kümmert sich nicht um etwas über 1K Länge. Sobald der Befehl gestartet wurde, wird der Befehlsname und die Argumentliste nicht benötigt. Daher wird das, was in der Prozesstabelle gespeichert wird, nur informativ.

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
}

12
2018-03-05 01:49



Nachteil ist, dass dies tatsächlich ein Zeichen mehr (vorne) als das ursprüngliche Muster entspricht. Zum Beispiel wird dies niemals mit der PID übereinstimmen. Und kann bei der Verwendung etwas irreführend sein grep --colour. - Tonin


+1 für @jamed knappe Antwort, aber das OP könnte eine Erklärung brauchen:

ps | grep "[d]jango"

Mit diesem Regex starten Sie einen Prozess, dessen ps-String nicht mit sich übereinstimmt, da der regexp passt "django" und nicht "[d]jango". Auf diese Weise werden Sie den Prozess ausschließen, der die Zeichenfolge "[d] jango" hat, in diesem Fall grep; Dasselbe gilt für pgrep, egrep, awk, sed usw., egal welchen Befehl Sie zum Definieren der Regex verwendet 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.

65
2018-03-09 07:54



Cool. Ich bin eigentlich ziemlich vertraut mit Regexs, konnte mir aber nicht sofort einen Weg vorstellen, den Regexp zu verhindern. Einen Buchstaben in eckigen Klammern zu setzen, macht Sinn. (Einschließlich etwas wie [^!] Würde auch funktionieren ...) - Steve Bennett
Das ist nett und schlau. - ash
Für den speziellen Fall 'ps' verwende ich '[]' am Anfang des Prozessnamens, nach dem ich suche. Dann muss ich den Prozessnamen nicht speziell für die Regex analysieren, aber es stimmt immer noch überein. - Neromancer
@hmontoliu Es funktioniert nicht zum Beispiel: ps aux | grep [s]cript1. Könnten Sie uns helfen, die Lösung zu kommentieren? - SOUser
@hmontoliu Meine Schuld. Es scheint, dass die Linie wegen der vorherigen Suchen gezeigt wird ... - SOUser


ps | grep [d]jango

ps | grep d[j]ango

...

ps | grep djang[o]


29
2018-03-09 07:10



Fügen Sie Leerzeichen hinzu, wenn Sie einen Char chartern müssen: ps aux| grep "[Z] " - A.D.
@jamzed Es funktioniert nicht zum Beispiel: ps aux | grep [s]cript1 oder ps aux | grep [s]cript2. Die Grep-Zeile wird weiterhin angezeigt. Könnten Sie uns helfen, die Lösung zu kommentieren? - SOUser
@jamzed Meine Schuld. Es scheint, dass die Linie wegen der vorherigen Suchen gezeigt wird ... - SOUser


Verwenden Sie stattdessen pgrep: pgrep -lf django


17
2018-03-09 06:19



Wie immer habe ich vergessen, die Plattform zu erwähnen (OS X in diesem Fall). Vermutlich arbeitet pgrep auf verschiedenen Linux-Rechnern. - Steve Bennett
Ich stimme nicht zu, @ramruma. Ich bin genau deswegen zu diesem Thema gekommen pgrepgibt mir genau dieses Problem. Aber ich muss sagen, ich teste es in CygWin (wo ps kann die vollständige Befehlszeile des Prozesses nicht anzeigen). - Sopalajo de Arrierez
Das Handbuch gibt an, dass "der laufende pgrep- oder pkill-Prozess sich niemals als Übereinstimmung melden wird", und tatsächlich habe ich es nicht gesehen. - deltab


Oh warte, das funktioniert:

ps | grep django | grep -v grep

11
2018-03-09 05:46



Nur wenn die Prozessbefehlszeile nicht zulässig ist grep, auf die man im allgemeinen Fall nicht zählen kann. - α CVn


ps -d | grep django

von mann ps:

 -d                  Lists information  about  all  processes
                     except session leaders.

8
2017-10-23 14:08



zeigt immer noch grep auf meiner ... - Kevin
Yep, das funktioniert für mich unter OS X. - Steve Bennett
Unter Linux funktioniert das nicht so gut. - A-B-B
Allgemeiner gesagt, die Optionen zu ps sind notorisch nicht portierbar, also ohne Informationen darüber, für welche Plattform das ist, ist diese Antwort nicht sehr hilfreich. Außerdem ist dies offensichtlich nicht angemessen, wenn Sie nicht sicher sind, dass der Prozess, den Sie suchen, kein Prozessleiter ist (d. H. Dies kann helfen, wenn Ihr Ziel ein Dämon ist, aber im Allgemeinen nicht anders). - tripleee