< 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はありません。
答え2
単純なコマンドの場合、リダイレクト位置決めは同じ行にあり、どこにでも柔軟です;
。
command1 arg <file
<file command1 arg
command1 <file arg
スタイル的には通常、最初の形式が好ましい。
パイプまたは条件を介してリンクされたコマンドの場合、リダイレクトはリンクされたコマンドと同じ側になければなりません。最初のコマンドが入力を受け取る必要がある場合は、次のことを行う必要があります。
command1 <file || command2
command2 が入力を受け取るには、次のようにします。
command1 || command2 <file
while
他のブロック複合コマンドの場合、リダイレクトをfor
最後に配置する必要性は単に構文論的な現実です。
<file { command1 || command2; } # error
{ command1 || command2; } <file # okay
たとえば、複合コマンドはこのコンテキストで単一のコマンドとして機能するため、リダイレクトされた入力はcommand2をターゲットにしてcommand1を除外できません。
もちろん、配管がオプションの場合もあるので、上記の2番目の例は次のとおりです。
cat file | { command1 || command2; }
whileループの場合:
cat myfile | while read a; do ...
これらの例ではすべて入力を使用していますが、出力にも同様に適用されます。注意すべき点は、入力と出力の両方を使用する場合、または他のマルチリダイレクト構成を使用する場合です。リダイレクトは左から右に処理されます。
もっと読む内容は次のとおりです。