web-dev-qa-db-ja.com

bashで開始されたバックグラウンドプロセスがstdoutを画面に出力するのはなぜですか?

私の状況を理解するのに苦労しており、Googleはこれまであまり役に立ちませんでした。

私はbashのバックグラウンドジョブを開始しました。

ping google.com &

最初にプロセスIDを取得しますが、Bashはstdoutを画面に出力します。

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
...

これは、私が今日読んだすべてのものと矛盾しています。 GNU bash、バージョン4.3.30(1)-release(x86_64-pc-linux-gnu))を実行している標準のDebian Jessieセットアップを持っています。

誰か私にこれを説明できますか?ありがとう。

10

デフォルトでは、少なくともPOSIX準拠システムの場合、&を使用してバックグラウンドでコマンドを実行すると、stdinだけがデタッチされるため、他のコマンドを実行できます。 stdoutstderrは引き続き親シェルにアタッチされています。

stdoutstderrを表示したくない場合は、ファイルまたは/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
14
petry

バックグラウンドプロセスのstdoutをターミナルに表示するかどうかは、あなた次第です。 sttyユーティリティを使用して動作を変更できます。

デフォルトでは、バックグラウンドプロセスが端末に書き込むことができます。

$ echo Hello &
[1] 25850
Hello
$

その動作はsttyコマンドで変更できます:

$ stty tostop
$ echo Hello &
[2] 25873

[2]+  Stopped                 echo Hello
$ 

tostopを指定すると、stdoutに書き込もうとしたときにバックグラウンドプロセスが停止します。続行させたい場合は、フォアグラウンドに戻すことができます。

$ fg
echo Hello
Hello
$

元に戻すには、stty -tostopを実行します。これが実行された後、作成されたnewバックグラウンドジョブはstdoutへの書き込みが許可されます。 (既存のジョブは影響を受けません。)

ドキュメンテーション

man sttytostopオプションについて次のように説明しています。

* [-]止まる
端末への書き込みを試みるバックグラウンドジョブを停止します

上記の先頭の*は、このオプションを非POSIXとして識別するためにmanページで使用されています。

7
John1024