< myfile
コマンドで入力または出力(、または)の> myfile
リダイレクトを提供するには、test-commands
consequent-commands
command1
command2
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; bar
foo | bar
{ foo && bar; } <myinput
スクリプト
while read a; do
echo "$a"
done <myfile
そして
while read a <myfile; do
echo "$a"
done
どちらも構文的に正確ですが、2番目のものは役に立つことはありません。コマンドのリダイレクト演算子は、次のことを意味します。
- 指定されたファイルを開きます。
- 指定されたファイルを必要なファイル記述子に追加します(たとえば、0はを意味します
<
)。 - コマンドを実行します。
- ファイル記述子を閉じます。
したがってread a <myfile
、繰り返すたびにファイルが再び開きます。つまり、最初の行を永遠に読みます。
読み込み中にループを使用し、ループ本体の周囲の標準入力を保持するには、別のファイル記述子から読みます。
while read a <&3; do
# commands that can use stdin
done 3<myfile
リダイレクト演算子は<&3
ファイル記述子のコピーのみを実行し、「ファイルを再開しません」。上記の列挙にはステップ1はありません。