リダイレクトの順序


29

コンピューターがこのコマンドをどのように読み取るかはよくわかりません。

cat file1 file2 1> file.txt 2>&1

理解できれば、2>&1単に標準エラーを標準出力にリダイレクトします。

そのロジックにより、コマンドは次のように読み取られます。

  1. ファイルfile1file2

  2. stdoutこの操作からに送信しfile.txtます。

  3. に送信stderrstdoutます。

  4. 終わり?

コンピューターが何をしているのかわかりません。私の論理では、コマンドは

cat file1 file2 2>&1 > file.txt

しかし、これは正しくありません。

回答:


46

割り当ての使用は簡単に考えられます。

  • > のようなものです =
  • & のようなものです $

で始まる

1 = /dev/tty
2 = /dev/tty

その後、最初の例は1> file.txt 2>&1

1 = file.txt
2 = $1           # and currently $1 = file.txt

あなたを残す

1 = file.txt
2 = file.txt

あなたが他の方法でそれをした場合、再びあなたは

1 = /dev/tty
2 = /dev/tty

その後2>&1 > file.txt

2 = $1           # and currently $1 = /dev/tty
1 = file.txt

最終結果は

1 = file.txt
2 = /dev/tty

そして、あなたはリダイレクトしているだけで、リダイレクトstdoutしていませんstderr


私は一種の類推を得ますが、それは混乱しています-何の$略ですか?
エリランマルカ

以下のような代入ではvar=$othervar$右側の変数名を紹介します。以下のようなリダイレクトでは2>&1&右側のファイルディスクリプタ番号を導入しています。「ファイル2はファイル1に等しい」と考えることができると言っています。(ただし、2つのタイプのイコールがあります。<「読み取り」と>「書き込み」を意味します。)
Mikel

12

リダイレクトの順序は重要であり、左から右に読む必要があります。

例えば: command 2>&1 >somefile意味:

  1. stderr(つまり2現在にリダイレクトします宛先stdout(この時点で端末)に。
  2. 次にstdout、に移動しますsomefileます。

この場合、 stderrターミナルにstdout移動し、ファイルに移動しますが、これはおそらく望んでいないことです。

一方、 command >somefile 2>&1ことを意味します。

  1. リダイレクト stdoutsomefile
  2. 次にstderrstdout(と同じ宛先にリダイレクトしますsomefile)ます。

この最後のケースでは、stderrとの両方にstdout進みsomefileます。これはおそらくあなたが望むものです。


4
cat file1 file2 1> file.txt 2>&1

>& 実際には複製を意味し、dupシステムコールを使用して、新しいファイル記述子を既に開いているファイルにマッピングします。

そのため、(実際にはbash)最初に新しいstdoutを開き、「stderrを現在設定されているstdoutにリダイレクトする」必要があります。


これはすごい!私はそれについて疑問に思っていました&。その構文へのいくつかの参照を同封できますか、または-さらに良いことに-前述のdupシステムに関するいくつかの優れたリソースですか?
エリランマルカ

1
「man dup」はシステムコールを文書化します。
X Tian

理にかなっている:)
感謝
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.