
stdoutとstderrの両方を同じファイルにリダイレクトする方法が2つあることがわかりました。最初の方法は次の
ls -l /bin > ls-output.txt 2>&1
とおりです。この本状態: この方法を使用すると、2 つのリダイレクトが実行されます。最初に stdout を ls-output.txt にリダイレクトし、次に stderr (ファイル記述子 2) を stdout (ファイル記述子 1 を使用) にリダイレクトします。
リダイレクトの順序は重要です。
ls -l /bin 2>&1 >ls-output.txt
stderr を screen にリダイレクトします。
私の質問は、多くのプログラミング言語と同様に、コマンドは結合性と優先順位のルールを考慮して設計されたのかということです。そして画面にコマンドを書き込みながら、そのコマンドをどのように読み取るのでしょうか?そしてコマンドのバックエンド実行のシーケンスは何ですか?
実行シーケンスについて私が思うことは次の通りです。まず、コマンドはls -l /bin
出力を stdout に、エラーを stderr(いずれか) に送信します。次に、stderr は stdout にリダイレクトされます(エラーがある場合、たとえば、 がls -l /binn
使用されている場合)。これで、stdout ストリームには 2 つのうちの 1 つ(出力またはエラー)が含まれ、それがファイルにリダイレクトされます。ls-出力.txt
答え1
リダイレクトは左から右に処理されます。以下を実行すると、
ls -l /bin >ls-output.txt 2>&1
シェルは内部的におおよそ次の操作を実行します。
fork(); // Then in the child process:
fd = open("ls-output.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
dup2(fd, 1);
close(fd);
// 2>&1
dup2(1, 2);
次に、ls -l /bin
これらの記述子の添付を使用してコマンドを実行します。stdout
最初にファイルにリダイレクトするため、 のリダイレクトはstderr
そのリダイレクトを継承します。
もしあなたが書くなら
ls -l /bin 2>&1 >ls-output.txt
演算の順序は逆になります。
// 2>&1
dup2(1, 2);
// >ls-output.txt
fd = open("ls-output.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
dup2(fd, 1);
close(fd);
これはstderr
元stdout
の (おそらく端末)に接続します。その後、stdout
ファイルにリダイレクトします。これは には影響しませんstderr
。