重定向是一个很有趣的话题,重定向这项技术减轻了程序编写者的负担,因为他只需要默认操作标准输入输出即可,而实际的标准输入可能是一个文本文件,而这一步的替换由shell来实现,不需要我们来操心,对程序来说是透明的。

这里的命令默认都是在bash下,如果你使用的是其他的比如csh,那么请查阅相关的手册或资料。

先来挑战一下你的理解能力,在你第一眼看到下面这行的时候你知道它在干嘛吗?

  1. outout-cmd 3>&1 1>&2 2>&3 3>&- | mail yourname

这是一个取自”Unix Power Tools”的例子,这个的功能先按下不表,先来讲讲重定向的一些基本规则。

  • 重定向的位置可以写在命令的前面或者后面,要知道这样$ > output-file ls也是合法的哦。当然了,程序是用来给人读的,给人理解的,所以我们还是应该按照一般的写法,将这种重定向写到后面去。而bash处理重定向的顺序是从 左到右的,为什么要在这里特别提一下呢?因为顺序不同,可能引起的效果也截然不同,是我原来的一个例子。
  • 在重定向符号的前面我们可以任意的加上我们需要重定向的数字,一般的重定向标准输入我们使用的是 < input-file,而我们也可以在这里使用 3< input-file,这样的效果就是我们将该程序的3这个文件描述符重定向成了这个输入的文件。下面的这个程序可以作为一个简单的演示。
    1. int main()
    2. {
    3.         char buf[10];
    4.         size_t size;
    5.  
    6.         while ((size = read(3, buf, 10)) > 0) {
    7.                 write(1, buf, size);
    8.         }
    9.         return 0;
    10. }

    然后再shell下敲入./a.out 3< input-file,那么读入的就是这个文件,并将该文件打印出来,很没劲的一个演示,不是吗?但是它却说明了一些道理,那就足够了。

  • 有时候我们希望同时重定向标准输出和标准错误输出,可以采用&>word和>&word的方法, 这两种方法中比较推荐的是前者,至于为什么推荐,笔者尚不明朗。这两者等同于>word 2>&1的功能。是不是总是看到后者的身影啊,现在你可以抛弃它了,而使用前面的两种简便的方法来炫一下了。
  • 复制文件的标志符是一个很重要的内容,他的基本语法是这样的:[n]<&word和[n]>&word,表示将n这个标识符复制成和word一样的一个标识符。这里的一个特殊情况是[n]>&-就会将n标识符关闭。

好了,现在的基本知识都已经具备了,让我们来讲讲开头的那个例子吧。

3>&1表示将标识符3复制成和1一样,都是标准输出。
1>&2表示将标识符1复制成和2一样,此时1成了标准错误输出。
2>&3表示将标识符2复制成和3一样,由于前面的第一步我们将3变成了标准输出,现在2和3一样,也是标准输出。
最后的3>&-将标识符3关闭。也就是说3相当于是一个中间的临时变量,用来交换程序的标准输出和标准错误输出。
然后将该标准错误输出利用pipe传递到mail程序,将错误的消息发邮件给你。

很有趣吧?

最后考考你:如果说要把一个程序的标准输出放到一个文件中,而把该程序的错误输出利用pipe传递给mail程序,应该怎么做呢?大致的框架和上面的类似。