なぜいくつかの同様のbashコマンドがそれらのように動作するのだろうか。
私はbashスクリプトを持っていますfoo
:
#!/usr/bin/env bash
while true
do
echo "reading"
read data
echo $data
echo "stderr msg" >&2
sleep 1
done
これは、stdinから一度に1行を読み取り、同じ行を出力する無限ループです。 bashスクリプトもありますbar
:
#!/usr/bin/env bash
./foo &
次のコマンドは、Ubuntu18.04のターミナルのbash
(v。4.4.19)で実行されました(スクリプトが作業ディレクトリにあると仮定します)。
./foo &
この回答 に従って、stdinから読み取ろうとすると停止します。
予想通り、制御端末が強制終了されると強制終了されます。
(./foo &)
Stdinからの新しい入力が自動的に継続的に供給されているように見えます。 stdinから読み込もうとしたときに、停止しすぎてはいけませんか?取得したものが何であれ、エコーされたときに表示されないので、EOF文字だと思います。
制御端末が強制終了された後も実行を継続します。 ps
の出力を見ると、制御端末がpts /xから?に変わります。 disown
またはNohup
を使用せずに、これはどのように発生しましたか? (ただし、元の制御端末を強制終了した後、書き込みごとに「書き込みエラー:入出力エラー」が発生します。これは、そのstdoutが現在閉じている端末に関連付けられているためだと思います。正しいですか?)
bash -c "./foo &"
2)とまったく同じように動作するように見えます。
./bar
2)および3)とまったく同じように動作するように見えます。
スタートアップアプリケーションとしてbash -c "~/foo"
(&
なし)を追加する
2)、3)、4)と同様に動作しますが、次の違いがあります。
これらの違いはどれも私には奇妙に思えませんが、新しい入力が継続的に供給されているという事実だけです。
私の推測では、2)-5)はすべて、stdinが/dev/null
のようなものにリダイレクトされる種類のサブシェルを使用していますが、私は非常に確信がなく、より正確な答えを探しています。
シェルなしでジョブ制御を有効にして(たとえば、スクリプトまたは&
サブシェルで)(...)
を使用して実行されるコマンドには、 /dev/null
およびSIGINT
およびSIGQUIT
からリダイレクトされたstdinはSIG_IGN
に設定されます。 susv4から 標準 :
ジョブ制御が無効になっている場合(
set
、-m
を参照)、明示的なリダイレクトが実行される前の非同期リストの標準入力は、同じプロパティを持つファイルに割り当てられていると見なされます。/dev/null
として。ジョブ制御が有効になっている場合、これは発生しません。すべての場合において、標準入力の明示的なリダイレクトは、このアクティビティをオーバーライドするものとします。
./foo
スクリプトが「継続的に供給される」データであるというのは真実ではありません-/dev/null
から読み取ろうとするとEOF)を取得します-終了ステータスを確認する必要がありますread
の。
サブシェルは非対話型です。インタラクティブシェルのみが自動的に強制終了されます。