Note that the order of redirections is significant. For example, the command
ls > dirlist 2>&1
directs both standard output and standard error to the file dirlist,
while the command
ls 2>&1 > dirlist
directs only the standard output to file dirlist, because the
standard error was duplicated from the standard output before the standard
output was redirected to dirlist.
今、最後の部分が私を混乱させます。この場合、標準エラーが端末に出力され、STDOUT がディレクトリリストファイルに移動されます。そのようなことが起こりますが、マニュアルを理解するわけではありません。
「標準出力がディレクトリリストにリダイレクトされた後、標準エラーが標準出力からコピーされるためです」と言う必要があるようです。 STDOUTがファイルに渡される前にSTDERRがSTDOUTに転送された場合、ファイルにSTDOUTとSTDERRは含まれませんか?
誰でもこの問題を解決するのに役立ちますか?私の読解力が足りないせいか?この文脈では、「繰り返し」という言葉を使うのは私にとっては少し奇妙に見えます。たぶんこれは私を混乱させるかもしれません。
ベストアンサー1
コピーここで本当に重要な部分です。
リダイレクトされる前に、ファイル記述子がどこに行くかを見てみましょう。これは通常現在の端末です。たとえば、次のようになります。
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
:STDOUT
ls -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
私たちはまだターミナルに行かなければなりません。
ご覧のとおり、マニュアルページの順序は正しいです。
テストリダイレクト
今すぐテストしてみましょう。を使用すると、現在のプロセスがどこに行くか(fd 1を使用)と(fd 2を使用)をls -l /proc/$$/fd/
確認できます。STDOUT
STDERR
$ 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
STDOUT
ファイル記述子1(の場合)と2(の場合)が異なることを確認できます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はどこを指していますか?;-))