Warum wird bei einem Hintergrundprozess, der in Bash gestartet wurde, die Standardausgabe auf dem Bildschirm gedruckt?

5

Ich habe Probleme, 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 dem 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 lese. 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? Vielen Dank.

Katja Eichelberger
quelle

Antworten:

9

Zumindest bei POSIX-kompatiblen Systemen wird standardmäßig ein Befehl im Hintergrund mit ausgeführt &, löst sich nur stdinDamit können Sie andere Befehle ausführen. stdout und stderr sind immer noch mit der übergeordneten Shell verbunden.

Wenn du nicht sehen willst stdout und / oder stderr Sie können sie einfach in eine Datei umleiten 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
petry
quelle
Unter MacOSX funktioniert das nicht.
Ogier Schelvis
@OgierSchelvis: Natürlich.
Kundor
Gibt es einen Weg, um wieder anzubringen stdin in diesem Fall?
alecov
4

Ob ein Hintergrundprozess auf dem Terminal angezeigt wird, bleibt Ihnen überlassen. Sie können das Verhalten mit dem ändern stty Nützlichkeit.

Beispiel

Standardmäßig kann ein Hintergrundprozess in das Terminal schreiben:

$ echo Hello &
[1] 25850
Hello
$

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

$ stty tostop
$ echo Hello &
[2] 25873

[2]+  Stopped                 echo Hello
$ 

Mit tostop angegeben, wird der Hintergrundprozess angehalten, wenn versucht wird, in stdout zu schreiben. Wenn Sie zulassen möchten, dass es fortgesetzt wird, können Sie es wieder in den Vordergrund bringen:

$ fg
echo Hello
Hello
$

Um zurückzuschalten, laufen Sie stty -tostop. Nachdem dies ausgeführt wird, Neu Hintergrundjobs, die erstellt werden, dürfen auf stdout schreiben. (Bestehende Jobs sind nicht betroffen.)

Dokumentation

man stty erklärt die tostop Option wie folgt:

* [-]stoppen
Beenden Sie Hintergrundjobs, die versuchen, auf das Terminal zu schreiben

Die Führung * Oben wird von der Manpage verwendet, um diese Option als Nicht-POSIX zu kennzeichnen.

John1024
quelle