whileループとドキュメントはここにあります。いつ何が起こりますか?

whileループとドキュメントはここにあります。いつ何が起こりますか?

私はこのwhileループをここのドキュメントと組み合わせてBash 4.3.48(1)で実行していますが、そのロジックをまったく理解していません。

while read file; do source ~/unwe/"$file"
done <<-EOF
    x.sh
    y.sh
EOF

私の質問は次の部分で構成されています。

  1. ここでやるべきことread(私は常にread変数を宣言し、値を割り当てるために使用します)。インタラクティブにしかし、ここでやるべきことを見逃しました)。

  2. どういう意味ですかwhile read?ここの概念はどこwhileから来ましたか?

  3. 文書自体がここに表示される場合後ろにループ、ループはどのような影響を受けますか?私の言葉は、doneループ内ではなく後ろに現れますが、これら2つの構造間の実際の接続は何ですか?

  4. なぜ失敗したのですか?

    while read file; do source ~/unwe/"$file" done <<-EOF
        x.sh
        y.sh
    EOF
    

    私の言うことは、はい...それでは、doneループと同じ行にあるのはdoneなぜ重要ですか?私の記憶が正しい場合は、done <<-EOFループは1行ですが、まだ機能している状況に遭遇したことがあります。for

答え1

  1. このreadコマンドは、標準入力ストリームから読み込んで読み取った内容を変数に割り当てますfile(これよりも少し複雑です.ここで長い議論)。標準入力ストリームはhere-documentで提供され、afterループにリダイレクトされますdone。データが提供されない場合どこでも、端末から対話的に読みます。ただし、この場合、シェルは入力ストリームをこのドキュメントにリンクするように配置しました。

  2. while readreadコマンドがゼロ以外の終了状態を返すまで、ループが繰り返されます。これは、エラーがある場合、または(最も一般的に)読み取られるデータがない場合(入力ストリームがファイル終了状態の場合)に発生します。

    通常、呼び出しシェルにエラーまたは「false」または「no」シグナルを送信しようとするすべてのユーティリティは、ゼロ以外の終了ステータスを返してシグナルを送信します。 0 終了ステータスは、「true」、「yes」、または「error no error」を意味します。このステータスを確認しますか?$?(最後に実行されたユーティリティでのみ)終了ステータスは、ifドアwhileとループ、またはテストが必要な任意の場所で利用できます。例えば

    if grep -q 'pattern' file; then ...; fi
    
  3. ここにある文書は次のとおりです。リダイレクトの一形態。この場合、ループにリダイレクトされます。ループ内のすべての内容を読み取ることができますが、この場合はコマンドのみを読み取るreadことができます。ここでマニュアルを読んでください。入力が通常のファイルから来る場合、最後の行は次のようになります。

    done <filename
    

    ループをコマンドとして考えると、より直感的になります。

    while ...; do ...; done <filename
    

    これは状況です。

    somecommand <filename
    

    一部のシェルは「here-strings」もサポートしています<<<"string"

    cat <<<"This is the here-string"
    

    David Posterは次のように指摘しています。両方のスクリプトのいずれかがファイルまたは他の場所から読み取るデータを明示的に提供せずに標準入力から読み取るx.sh場合、読み取ったデータは実際にはhereドキュメントから来ます。y.sh

    x.shにのみ含まれる場合、read a変数aに文字列が含まy.shれ、y.shスクリプトは実行されません。これは、標準入力が次のようにリダイレクトされるためです。みんなコマンドをループに追加するとwhile(呼び出しスクリプトまたはコマンドによって「継承」)、2番目の行はループがx.sh読み取れる前に「使用」されます。whileread

    この動作が望ましくなく防止できる場合しかし、ちょっと面倒です。

  4. ;前に改行文字がないため失敗しますdone。前に;a または改行文字がない場合、doneその単語はdone引数として扱われ、sourceループも正しく閉じられません (構文エラーです)。

    すべてを改行で置き換えることができることはほとんど事実です;(少なくともコマンド区切り文字の場合)。|、、、&および(おそらく忘れた他のものもあります)の&&よう||に、コマンドの終わりを表示します。

答え2

デフォルトでは、オブジェクトをドキュメントとして生成してからwhileループにリダイレクトし、残りの行がないまで1行ずつ読み込み、その行でソースコマンドを実行します。

別の方法は次のとおりです。

仮想線

x.sh
y.sh

次のファイルから:

input.txt

我々は実行することができます

cat input.txt | while read file
   do source ~/unwe/"$file"
done

ここのドキュメントは作業をよりインタラクティブにしますが、上記の例を見ると、より良いアイデアが得られます。

関連情報