复制实际上是这里的重要部分。
让我们看一下重定向之前文件描述符的去向。这通常是当前端子,例如:
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仍然要去码头。
您会看到手册页中的顺序是正确的。
测试重定向
现在,您可以自己进行测试。使用ls -l /proc/$$/fd/,您可以看到STDOUT(使用fd 1的)和STDERR(使用fd 2的)当前进程的位置:
$ 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
让我们创建一个小的shell脚本,该脚本显示文件描述符指向的位置。这样,我们总是在调用时获得状态ls,包括从调用shell进行的任何重定向。
$ 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(用于STDOUT)和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指向哪里?;-))