複合コマンドに使用されるコマンドリダイレクトの提供

複合コマンドに使用されるコマンドリダイレクトの提供

< myfileコマンドで入力または出力(、または)の> myfileリダイレクトを提供するには、test-commandsconsequent-commandscommand1command2

if test-commands; then
consequent-commands;

until test-commands; do consequent-commands; done

while test-commands; do consequent-commands; done

command1 && command2

command1 || command2

リダイレクトはどこに配置する必要がありますか?

たとえば、私は見る

while read a; 
  do echo "$a"; 
done < myfile;

< myfileなぜ裏側doneではなく裏側なのか気になりますread a

また(この記事の最初の段落のように)もっと広く考えることになりました。

  • 複合コマンドに表示されるコマンドはどこに配置する必要がありますか?

  • リダイレクトが出力か入力かは重要ですか?

  • 複合コマンドの最後にリダイレクトを入れると、リダイレクトが適用される複合コマンド内のどのコンポーネントコマンドをどのように知ることができますか?

ありがとうございます。

ベストアンサー1

単純なコマンド内のどこにでもリダイレクトを配置できます(エイリアス、関数、組み込み関数、または引数を使用して実行可能ファイルを呼び出すなど)。一方、複合コマンドにリダイレクトを適用するには、後でリダイレクトする必要があります。これがシェル構文が設計された方法です。たとえば、次は同じです。

<myinput mycommand argument
mycommand <myinput argument
mycommand argument <myinput

リダイレクトを移動できません。

while …; do …; done <myinput
{ command1; command2; } <myinput

複合コマンドがキーワードまたは句読点で終わる場合にのみ、リダイレクトを適用できます。または、同じアイテムにリダイレクトを適用するには、foo && bar次のように中括弧内にコマンドを入れます。foo; barfoo | bar

{ foo && bar; } <myinput

スクリプト

while read a; do
  echo "$a"
done <myfile

そして

while read a <myfile; do
  echo "$a"
done

どちらも構文的に正確ですが、2番目のものは役に立つことはありません。コマンドのリダイレクト演算子は、次のことを意味します。

  1. 指定されたファイルを開きます。
  2. 指定されたファイルを必要なファイル記述子に追加します(たとえば、0はを意味します<)。
  3. コマンドを実行します。
  4. ファイル記述子を閉じます。

したがってread a <myfile、繰り返すたびにファイルが再び開きます。つまり、最初の行を永遠に読みます。

読み込み中にループを使用し、ループ本体の周囲の標準入力を保持するには、別のファイル記述子から読みます。

while read a <&3; do
  # commands that can use stdin
done 3<myfile

リダイレクト演算子は<&3ファイル記述子のコピーのみを実行し、「ファイルを再開しません」。上記の列挙にはステップ1はありません。

おすすめ記事