Dies ist ein perfekt zu erwartendes Verhalten, aber vielleicht etwas verwirrend, wenn Sie nicht genau wissen, was die beteiligten Befehle tatsächlich tun. Und nein, es ist keine Schurken-Software beteiligt. Ich werde versuchen zu erklären, was hier tatsächlich passiert.
Wenn Sie ausführen ps ax
, erhalten Sie zunächst eine Liste aller auf dem System ausgeführten Prozesse und (einiger) ihrer Befehlszeilenargumente.
Zweitens, wenn Sie diesen Befehl ausführen grep "nginx"
, wird er von der Standardeingabe gelesen (da Sie keine Datei zur Verwendung als Eingabe angegeben haben) und alle Zeilen ausgegeben, die die Zeichenfolge enthalten nginx
.
In der Shell eines Unix-ähnlichen Systems (wie Mac OS X) werden Pipes im Allgemeinen so implementiert, dass Befehle grundsätzlich von rechts nach links gestartet werden, Daten jedoch von links nach rechts transportiert werden.
Folgendes passiert also: Zuerst grep
wird mit dem Argument begonnen nginx
. Zweitens ps
wird mit dem Argument begonnen ax
, und seine Standardausgabe ist an die Standardeingabe des grep
Prozesses gebunden . Wie ps
ausgeführt wird , wird seine Ausgabe an die Standardausgabe zugeführt ps
, das ist dasselbe wie die Standardeingabe grep
. Im Gegenzug grep
sieht bei jeder Zeile, für die Zeichenfolge suchen nginx
, denn das ist , was Sie gesagt , grep
zu tun. Eine solche Zeile erscheint einmal: der grep-Prozess selbst mit seinen Kommandozeilenargumenten! Als Ergebnis wird diese Zeile gedruckt grep
auf grepStandardausgabe und alle anderen werden unterdrückt. In Ihrem ersten Beispiel ist die Standardausgabe von grep nicht an einen anderen Prozess gebunden, sodass sie standardmäßig auf dem Terminal ausgegeben wird. Wenn es keine Daten mehr von gibt ps
, wird es grep
auch beendet, da alle Befehle miteinander verknüpft sind. Es macht keinen Sinn, wenn einer von ihnen ausgeführt wird, wenn ein anderer fertig ist.
Wenn Sie die Ausgabe von grep through awk
into xargs kill
leiten, erstellt xargs eine Liste der geplanten Aktionen, die jedoch erst am Ende ausgeführt werden. Also, bis xargs dazu kommt, kill aufzurufen, ist der grep-Prozess - der den nginx unter seinen Kommandozeilenparametern hatte - bereits weg. Daher gibt es keinen Prozess, an den Sie ein Signal senden und kill
Sie über diese Tatsache informieren können.
Wie Sie sehen, läuft auf Ihrem System kein Rogue-Nginx-Prozess, der Ihren Versuchen, ihn zu finden, ausweicht. Es gibt nur ein Grep, das wiederholt gestartet wird, einmal für jedes Mal, wenn Sie schauen, was sich selbst findet.
Sie können dies vermeiden, indem Sie irgendwo in der Suchzeichenfolge Zeichengruppen verwenden, da sich diese nicht selbst finden. Gibt zum Beispiel ps ax | grep foobar
den grep-Prozess zurück, ps ax | grep 'fooba[r]'
tut dies jedoch nicht, da dies fooba[r]
nicht dasselbe ist foobar
wie ein einfacher String. ( [r]
Stimmt r
also nur mit einem der Zeichen überein r
.) Beachten Sie, dass Sie dazu wahrscheinlich das Argument zu entkommen brauchen grep
.
Abgesehen davon ist es fast immer unnötig, zuerst grep
und dann awk
ohne irgendetwas anderes dazwischen zu laufen . Anstelle eines ... | grep 'foobar' | awk '{ print $2 }'
vorhergehenden Befehls ...
können Sie ... | awk '/foobar/ { print $2 }'
awk auch einfach beide Aufgaben ausführen lassen. Dies tritt am häufigsten auf cat
, wenn es als nutzlose Verwendung von cat bezeichnet wird , aber das Konzept lässt sich auch gut auf andere Befehle verallgemeinern, z. B. grep in Ihrem Fall.