子shell与文件重定向

发这篇日志源于在ubuntu中文论坛有人发帖提问一个怪现象。关于子shell与重定向。

实验一:

    内容:

        date>file1

    现象:

        标准输出无内容,file1中有内容。

 

实验二:

    内容:

        (date)>file1

    现象:

        标准输出无内容,file1中有内容。

    问题:

        我想的是,这个date会在子shell中运行,在子shell中date的输出并没有被重定向,所以date应该是在子shell的屏幕上打印日期,然后返回父shell,返回之后会碰到>file1命令。不管在这之后会怎么样,我就输入这条命令想测试下。没想到它竟然跟不加括号运行一样。一样是把输出重定向到了file1文件。有点想不通为什么。

 

实验三:

    内容:

        (date >file1) >file2

    现象:

        file1中有内容,file2中无内容。

 

实验四:

    内容:

        date >file1 >file2

    现象:

        file1中无内容,file2中有内容。

 

如果认真看过shell脚本编程中关于“文件描述符”以及“重定向”的内容的话,这个问题其实很简单。好吧,不装13了。

解释如下:

1、重定向发生的时间是在执行开始之前,而非结束以后。所以“子shell执行完,返回父shell后再碰到重定向命令”的说法是错误的。实际上是先发生重定向的动作,再去执行相应的命令或子shell。

2、重定向的作用:(这里以输出为例,输入类似)将本来由文件描述符A输出的内容改为由文件描述符B输出。造成的结果:一、文件描述符A输出为空。二、文件描述符B有输出。

3、对同一个文件描述符多次进行重定向操作,后发生的会覆盖先发生的操作,重定向的最终结果是最后一次重定向命令。

以下是对各实验的解释:

实验一:

date >file1

解释:

首先将date的标准输出重定向到文件file1,然后执行date命令。此时标准输出无内容,file1中有内容。

 

实验二:

(date) > file1

解释:

1、重定向发生在子shell开始的时候。所以,首先将子shell的标准输出重定向到文件file1,然后再执行子shell。

2、子shell中执行date命令,输出到标准输出。但由于此时标准输出已经重定向到文件file1中,所以标准输出无内容,文件file1中有内容。

 

实验三:

(date >file1) >file2

解释:

1、首先,将子shell的标准输出重定向到文件file2,然后执行子shell。

2、子shell中,将date的标准输出重定向到文件file1,然后执行date。

3、此时,date的输出送到file1,子shell执行完毕。造成的结果是:子shell的标准输出无内容,file1中有内容。

4、子shell退出,由于子shell的标准输出无内容,所以文件file2无内容。

 

实验四:

date >file1 >file2

解释:

1、首先将date的标准输出重定向到文件file1。

2、然后将date的标准输出重定向到文件file2,由于都是对同一个文件描述符的重定向,所以这一步会覆盖上一步的结果。

3、造成的结果就是,date的标准输出最终被重定向到文件file2。