Warum druckt ein in Bash gestarteter Hintergrundprozess die Standardausgabe auf den Bildschirm?

Warum druckt ein in Bash gestarteter Hintergrundprozess die Standardausgabe auf den Bildschirm?

Ich habe Schwierigkeiten, meine Situation zu verstehen, und Google war bisher nicht sehr hilfreich.

Ich habe einen Bash-Hintergrundjob gestartet:

ping google.com &

Zuerst erhalte ich die Prozess-ID, dann druckt Bash die Standardausgabe auf den Bildschirm.

user@host:~$ ping google.com &
[1] 14004
user@host:~$ PING google.com (173.194.44.66) 56(84) bytes of data.
64 bytes from ham02s14-in-f2.1e100.net (173.194.44.66): icmp_seq=1 ttl=54 time=26.3 ms
64 bytes from ham02s14-in-f2.1e100.net (173.194.44.66): icmp_seq=2 ttl=54 time=27.4 ms
64 bytes from ham02s14-in-f2.1e100.net (173.194.44.66): icmp_seq=3 ttl=54 time=29.2 ms
...

Das widerspricht allem, was ich heute gelesen habe. Ich habe ein Standard-Debian-Jessie-Setup mit GNU Bash, Version 4.3.30(1)-Release (x86_64-pc-linux-gnu).

Kann mir das jemand erklären? Danke.

Antwort1

Standardmäßig (zumindest bei POSIX-kompatiblen Systemen) wird beim Ausführen eines Befehls im Hintergrund mit &nur die Verbindung getrennt stdin, so dass Sie andere Befehle ausführen können. stdoutund stderrsind weiterhin mit der übergeordneten Shell verbunden.

Wenn Sie sie nicht sehen möchten stdoutund/oder stderrsie einfach in eine Datei umleiten können oder /dev/null:

command &>log.txt &                #stdout and stderr to log.txt
command 1>/dev/null &               #stdout to /dev/null, stderr still attached to shell
command 1>output.log 2>error.log &  #stdout to output.log, stderr to error.log

Antwort2

Ob stdout eines Hintergrundprozesses auf dem Terminal angezeigt wird, bleibt Ihnen überlassen. Sie können das Verhalten mit dem sttyDienstprogramm ändern.

Beispiel

Die Standardeinstellung erlaubt einem Hintergrundprozess, ins Terminal zu schreiben:

$ echo Hello &
[1] 25850
Hello
$

Dieses Verhalten kann mit dem folgenden Befehl geändert werden stty:

$ stty tostop
$ echo Hello &
[2] 25873

[2]+  Stopped                 echo Hello
$ 

Wenn tostopangegeben, wird der Hintergrundprozess angehalten, wenn er versucht, auf stdout zu schreiben. Wenn Sie zulassen möchten, dass er weiterläuft, können Sie ihn wieder in den Vordergrund bringen:

$ fg
echo Hello
Hello
$

Um zurück zu wechseln, führen Sie aus stty -tostop. Nachdem dies ausgeführt wurde,neuErstellte Hintergrundjobs dürfen in die Standardausgabe schreiben. (Bestehende Jobs sind hiervon nicht betroffen.)

Dokumentation

man sttyerklärt die tostopOption wie folgt:

* [-]tostop
stoppt Hintergrundjobs die versuchen, auf das Terminal zu schreiben

Der *oben stehende Vorsprung wird von der Manpage verwendet, um diese Option als Nicht-POSIX zu kennzeichnen.

verwandte Informationen