执行grep命令后文件描述符3为何出现状态变化?
文件描述符读取位置的疑问
操作场景
执行以下操作后,首次执行grep test_word <&3可输出结果,再次执行则无输出:
$ exec 3<input.txt $ sleep 60 >&3 & [1] 32524 $ cd /proc/32534/fd $ ls -l lrwx------. 1 zhangchen zhangchen 64 Sep 24 18:29 0 -> /dev/pts/0 lr-x------. 1 zhangchen zhangchen 64 Sep 24 18:29 1 -> /home/zhangchen/input.txt lrwx------. 1 zhangchen zhangchen 64 Sep 24 18:29 2 -> /dev/pts/0 lr-x------. 1 zhangchen zhangchen 64 Sep 24 18:29 3 -> /home/zhangchen/input.txt $ grep test_word <&3 test_word $ grep test_word <&3 [nothing output]
疑问
grep不是使用文件描述符1进行文件搜索吗?为何会改变文件描述符3的状态?
解答
核心要理清文件描述符和文件读取位置的关联逻辑:
- 执行
exec 3<input.txt时,文件描述符3以只读模式绑定到input.txt,此时对应的文件读取指针停在文件开头。 grep test_word <&3的作用是把grep的标准输入(文件描述符0)重定向为fd3的副本,但文件的读取位置是由底层文件表项维护的,所有指向同一文件表项的文件描述符共享这个指针。- 第一次执行grep时,它会从当前指针位置(文件开头)读取完整内容,匹配到目标字符串后,指针会移动到文件末尾。
- 第二次执行grep时,指针已经停在文件末尾,没有可读取的内容,因此无输出。
你对grep的文件描述符使用存在误解:grep默认从标准输入(fd0)读取内容,这里的<&3是将fd3的输入通道重定向给grep的fd0,而非让grep直接使用fd1。不管是fd0还是fd3,它们共享同一个文件的读取位置,所以第一次读取后指针的变化会影响后续所有基于该文件表项的读取操作。
另外,你执行的sleep 60 >&3实际是将fd1重定向到只读模式的fd3,这个操作无法写入文件,对后续grep的结果没有实质影响,只是在proc目录下能看到sleep进程的fd1指向了input.txt而已。
内容的提问来源于stack exchange,提问作者chen zhang
相关产品推荐
相关产品推荐

