子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。