複製ここでは、が本当に重要な部分です。
リダイレクトの前にファイル記述子がどこに行くのか見てみましょう。これは通常、現在の端末です。例:
STDOUT ---> /dev/pts/1
STDERR ---> /dev/pts/1
ここで、ls -lリダイレクトなしで呼び出すと、出力およびエラーメッセージがの下の端末に送られ/dev/pts/1ます。
最初にSTDOUTファイルにリダイレクトする場合(ls -l > dirlist)、次のようになります。
STDOUT ---> /home/bon/dirlist
STDERR ---> /dev/pts/1
私たちはときに、その後リダイレクトSTDERRに重複のSTDOUTのファイルディスクリプタ(ls -l > dirlist 2>&1)、STDERRの複製に行きます/home/bon/dirlist:
STDOUT ---> /home/bon/dirlist
STDERR ---> /home/bon/dirlist
最初にのファイル記述子()のSTDERR複製にリダイレクトする場合:STDOUTls -l 2>&1
STDOUT ---> /dev/pts/1
STDERR ---> /dev/pts/1
そしてその後、 STDOUTファイル(にls -l 2>&1 > dirlist)、我々はこれを得るでしょう:
STDOUT ---> /home/bon/dirlist
STDERR ---> /dev/pts/1
ここに、 STDERRは、まだターミナルに行きます。
ご覧のとおり、manページの順序は正しいです。
リダイレクトのテスト
これで、自分でテストできます。を使用すると、現在のプロセスの(fd 1で)および(fd 2で)ls -l /proc/$$/fd/どこに行くのかがわかります。STDOUTSTDERR
$ ls -l /proc/$$/fd/
total 0
lrwx------ 1 bon bon 64 Jul 24 18:19 0 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 18:19 1 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 07:41 2 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 18:19 255 -> /dev/pts/1
ファイル記述子が指している場所を示す小さなシェルスクリプトを作成しましょう。このようにしてls、呼び出しシェルからのリダイレクトを含め、を呼び出すときに常に状態を取得します。
$ cat > lookfd.sh
#!/bin/sh
ls -l /proc/$$/fd/
^D
$ chmod +x lookfd.sh
(を使用するとCtrlD、ファイルの終わりを送信するため、catからのコマンド読み取りを停止しSTDINます。)
次に、さまざまなリダイレクトの組み合わせでこのスクリプトを呼び出します。
$ ./lookfd.sh
total 0
lrwx------ 1 bon bon 64 Jul 24 19:08 0 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 19:08 1 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 19:08 2 -> /dev/pts/1
lr-x------ 1 bon bon 64 Jul 24 19:08 255 -> /home/bon/lookfd.sh
$ ./lookfd.sh > foo.out
$ cat foo.out
total 0
lrwx------ 1 bon bon 64 Jul 24 19:10 0 -> /dev/pts/1
l-wx------ 1 bon bon 64 Jul 24 19:10 1 -> /home/bon/foo.out
lrwx------ 1 bon bon 64 Jul 24 19:10 2 -> /dev/pts/1
lr-x------ 1 bon bon 64 Jul 24 19:10 255 -> /home/bon/lookfd.sh
$ ./lookfd.sh 2>&1 > foo.out
$ cat foo.out
total 0
lrwx------ 1 bon bon 64 Jul 24 19:10 0 -> /dev/pts/1
l-wx------ 1 bon bon 64 Jul 24 19:10 1 -> /home/bon/foo.out
lrwx------ 1 bon bon 64 Jul 24 19:10 2 -> /dev/pts/1
lr-x------ 1 bon bon 64 Jul 24 19:10 255 -> /home/bon/lookfd.sh
$ ./lookfd.sh > foo.out 2>&1
$ cat foo.out
total 0
lrwx------ 1 bon bon 64 Jul 24 19:11 0 -> /dev/pts/1
l-wx------ 1 bon bon 64 Jul 24 19:11 1 -> /home/bon/foo.out
l-wx------ 1 bon bon 64 Jul 24 19:11 2 -> /home/bon/foo.out
lr-x------ 1 bon bon 64 Jul 24 19:11 255 -> /home/bon/lookfd.sh
ファイル記述子1(for STDOUT)および2(for STDERR)が異なることがわかります。楽しみのために、リダイレクトSTDINして結果を確認することもできます。
$ ./lookfd.sh < /dev/zero
total 0
lr-x------ 1 bon bon 64 Jul 24 19:18 0 -> /dev/zero
lrwx------ 1 bon bon 64 Jul 24 19:18 1 -> /dev/pts/1
lrwx------ 1 bon bon 64 Jul 24 19:18 2 -> /dev/pts/1
lr-x------ 1 bon bon 64 Jul 24 19:18 255 -> /home/bon/lookfd.sh
(質問は読者に任されました:ファイル記述子255はどこを指しますか?;-))