Bashシェルコマンドのリダイレクトはどこに配置しますか? [コピー]

Bashシェルコマンドのリダイレクトはどこに配置しますか? [コピー]

重複の可能性:
注文リダイレクト

現在のシェルの入力と出力を独立してリダイレクトする以外に、exec >&2次のコマンドの動作に違いはありますか?

  1. echo -en "C\nB\nA\n" | sort 2>/dev/stdout >&2
  2. echo -en "C\nB\nA\n" 2>/dev/stdout >&2 | sort
  3. 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に何も出力しないため、空のsortstdinが表示されます。

コマンドブロックを中括弧で囲み、コマンドブロックの入力または出力をリダイレクトできます。

{ command1 | command2; } 2>error.log

私はあなたが選択したリダイレクトがデモ目的にすぎないと仮定します。2>/dev/stdout >&2作成するのは複雑です2>&1(標準エラー(fd 2など)を現在の標準出力(fd 1など)がある場所にリダイレクトします)。

おすすめ記事