重複の可能性:
注文リダイレクト
現在のシェルの入力と出力を独立してリダイレクトする以外に、exec >&2
次のコマンドの動作に違いはありますか?
echo -en "C\nB\nA\n" | sort 2>/dev/stdout >&2
echo -en "C\nB\nA\n" 2>/dev/stdout >&2 | sort
2>/dev/stdout >&2 echo -en "C\nB\nA\n" | sort
上記のコマンドが同じであれば、好ましい変形は何ですか?
答え1
まず、簡単なコマンド(デフォルトでは、プログラム名の後にはいくつかのパラメータが続きます。)パラメータとリダイレクトの相対位置は重要ではありません。コマンド名の前にリダイレクトすることもできます。以下はすべて同じです。
foo --bar qux >out 2>err
foo >out --bar 2>err
>out 2>err foo --bar qux
(すべての可能性をリストしているわけではありません。)リダイレクトを最後に置くのが一般的なので、そうでなければ将来の読者は驚くかもしれません。しかし、これはスタイルの問題です。コマンドの前に入力リダイレクトを配置し、コマンドの後に出力リダイレクトを配置すると、特にパイプラインでの読み取り順序が処理順序と同じになるため、いくつかの利点があります。
<input.txt command1 | command2 | command3 >output.txt
(command1 <input.txt | command2 …
最初の処理ステップの後に原点を配置することとは対照的です。)
複合コマンドでは、リダイレクトを最後に配置する必要があります。たとえば、次のコードスニペットでは、リダイレクトを他の場所に配置することはできません。
while some_predicate; do some_action; done <in >out
{ command1; command2; } <in >out
複数のリダイレクトがある場合は重複する場合、つまり共通ファイル記述子がある場合は順序が重要です。バラより注文リダイレクト
パイプラインでは、リダイレクトはすべてのパイプラインコマンドに適用されます。あなたの例では、リダイレクトはsort
(1)コマンドと(2,3)echo
コマンドでのみ機能します。前述したように、(2)と(3)は同じです。
(2)と(3)では、出力はecho
リダイレクト前に同じ位置で終了します。と書くと、echo -en "C\nB\nA\n" >&2 | sort
パイプの左側にあるコマンドはstdoutに何も出力しないため、空のsort
stdinが表示されます。
コマンドブロックを中括弧で囲み、コマンドブロックの入力または出力をリダイレクトできます。
{ command1 | command2; } 2>error.log
私はあなたが選択したリダイレクトがデモ目的にすぎないと仮定します。2>/dev/stdout >&2
作成するのは複雑です2>&1
(標準エラー(fd 2など)を現在の標準出力(fd 1など)がある場所にリダイレクトします)。
答え2
1は2、3とは異なります。 2と3は同じです。
バージョン 1 では、C\nB\nA\n
に送信される FD 2 が元の宛先 ( ) で にマッピングされsort
、その後、とにかく到着した FD 1 が に送信されます (やや無意味)。sort
STDERR
STDOUT
STDOUT
sort
STDOUT
バージョン 2 および 3 では、echo
FD 2 がSTDERR
元の宛先 () からマッピングされたSTDOUT
後、どうせ到着した FD 1 が 'STDOUT
に送信されます。echo
STDOUT
機能的には、これらのコマンドのいずれかSTDERR
。
バージョン1では、echo
何かをFD 2に出力するとFD 2に移動しますSTDERR
が、バージョン2と3ではに移動しますSTDOUT
(したがってパイプでも接続されますsort
)。また、バージョン1ではsort
FD 2に何かを送信するとに移動しますが、STDOUT
バージョン2と3では対応する出力がに移動しますSTDERR
。
「好みのバリエーション」に関する限り、実際には次のようなものをさらに使用する必要がありecho
ますSTDERR
。sort
echo -en "C\nB\nA\n" 2>&1 | sort
これは、FD 1が既定で既に含まれており、STDOUT
FD 2がファイル記述をその記述子にコピーできるようにするために機能します。