Die PID des vorherigen Befehls in der Hintergrund-Pipeline

Die PID des vorherigen Befehls in der Hintergrund-Pipeline

Ich habe ein Skriptfragment:

MyCoolCommand 2>&1 | tail -n 256 > "report.out" &
cool_pid=$!  # FIXME

Es hat einen Fehler – cool_pides ist die PID von tail. Die Pipeline läuft im Hintergrund. Wie kann ich die cool_pidPID von speichern MyCoolCommand? Die Shell ist /bin/sh. Wenn das mit dem alten, einfachen /bin/sh nicht möglich ist, bin ich bereit, auf Bash umzusteigen, wenn es eine Möglichkeit gibt, das zu erreichen.

Antwort1

In Bash können Sie Prozesssubstitution verwenden:

MyCoolCommand > >(tail -n 256 > report.out) 2>&1 &
cool_pid=$!

Die Daten fließen MyCoolCommandwie tailbei Ihrem ursprünglichen Befehl von „nach“ und $!entsprechen Ihren Wünschen.

Anmerkungen:

  • 2>&1muss nach>.
  • Die Shell betrachtet die Arbeit unmittelbar nach dem Beenden als MyCoolCommanderledigt, währendtailläuft möglicherweise noch. Wenn Ihr Skript irgendwann waits für den Job und dann report.outweiter verarbeitet, denken Sie daran, dass die Datei möglicherweise noch nicht fertig ist. Zum Vergleich: Ihr Skript MyCoolCommand | tail … &gilt als fertig, nachdembeideProzesse werden beendet.

Sie können das Problem einfach lösen sh, dazu sind jedoch manuelle Schritte erforderlich:

mkfifo myfifo
<myfifo tail -n 256 >report.out &
MyCoolCommand >myfifo 2>&1 &
cool_pid=$!
rm myfifo

Anmerkungen:

  • Das Entfernen des FIFO, wenn es noch verwendet wird, ist sicher. Die Programme werden es weiterhin verwenden, obwohl es nicht mehr mit dem Verzeichnis verknüpft ist. Das Betriebssystem wird das FIFO erst dann wirklich zerstören, wenn es nicht mehr verwendet wird. Eine neue Datei mit dem Namen myfifo(falls sie jemals erstellt wurde) hat nichts mit der alten zu tun (außer dem Namen), selbst wenn die alte noch verwendet wird.

  • Wenn sich eine Datei mit dem Namen myfifobereits im aktuellen Arbeitsverzeichnis befindet (weil eine andere Instanz des Skripts parallel ausgeführt wird oder aus irgendeinem anderen Grund) und möglicherweise verwendet wird, kann es sein, dass das Skript nicht richtig funktioniert. Das Richtige wäre, ein temporäres Verzeichnis mit zu erstellen mktemp -dund dort ein FIFO zu platzieren. mktempist nicht portierbar.

  • Mit dieser Methode können Sie die PID vonMyCoolCommand Undunabhängig die PID von tail.

verwandte Informationen