バックグラウンドプロセスのサブシェル奇妙な動作

バックグラウンドプロセスのサブシェル奇妙な動作

同様の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 &

次のコマンドは、bashUbuntu 18.04の端末(v.4.4.19)で実行されます(スクリプトが作業ディレクトリにあると仮定)。

  1. ./foo &

    • 次のように標準入力から読み取ろうとすると停止します。この回答

    • 予想通り制御端末が終了すると終了します。

  2. (./foo &)

    • 新しい入力は標準入力で自動的に継続的に提供されるようです。標準入力から読み取ろうとするときは止まらないのですか?何が得られてもエコーされると表示されないので、EOF文字であると推測されます。

    • 制御端末が終了した後も実行を続けます。出力を表示するには、ps制御端末がpts /から次に変わります。X到着? 。 orを使用せずにdisownどうなりますかnohup? (ただし、元の制御端末を殺してから書き込むたびに「書き込みエラー:入出力エラー」が発生しますが、その標準出力が閉じた端末に接続されているためですね。)

  3. bash -c "./foo &"

    動作は2)とまったく同じようです。

  4. ./bar

    2)、3)とまったく同じです。

  5. 起動アプリケーションとして追加bash -c "~/foo"(いいえ)&

    動作は2)、3)、4)に似ていますが、次のような違いがあります.

    • 制御端末はデスクトップttyです。X
    • あなたは制御端末を殺すことはできません。

    違いは私にとって驚くべきことではなく、新しい入力が常に注入されているということです。

私の考えでは、2) - 5)すべてのstdinが似ているようにリダイレクトされているサブシェルの一種を使用しています/dev/nullが、私は確かではなく、より正確な答えを探しています。

ベストアンサー1

&シェルで実行するコマンドいいえアクティブなジョブ制御(スクリプトまたは(...)サブシェルなど)の標準入力は、でリダイレクトされ、に/dev/null設定されSIGINTます。 susv4からSIGQUITSIG_IGN基準:

ジョブ制御が無効になっている場合(参照set-m、非同期リストの標準入力は、明示的なリダイレクトが実行される前に同じ属性を持つファイルに割り当てられているかのように処理する必要があります/dev/null。ジョブ制御が有効な場合、これは発生しません。すべての場合において、標準入力の明示的なリダイレクトはこのアクティビティを上書きする必要があります。

また、見ることができますこれそしてこれ

あなたのスクリプトがデータを「継続的に入力する」ことが正しくありません。./foo読み取ろうとするとEOFを受け取ります。/dev/null確認する必要がありますread

おすすめ記事