先写一个语义不太清晰的写法:
1 |
exec 1<>/tmp/file |
通常来讲,1是标准输出,如果我们要重定向标准输出到文件 /tmp/file , 则写法如下:
1 |
exec >/tmp/file |
这里没有写文件描述符,默认为输出重定向说的就是文件描述符1,即:
1 |
exec 1>/tmp/file |
那么,你可能会说:
1 |
exec 1<>/tmp/file |
也有这个效果,那么这个有如何解释呢?
该命令逻辑上等效于: (实际上不是)
1 |
exec 1</tmp/file && exec 1>/tmp/file |
前面是说的输入重定向,后面说的是输出重定向;
但是,通常我们不会去读标准输出的,虽然0/1/2 和其它文件描述符都是一样的。
下面看一个实际测试:
因为每个文件描述符只有一个位置指针,读写操作的指针不是分开的,所以,这里我们是从文件尾部开始read的,所以啥也read不到,能否跳转到文件头read呢?
这里有很多有意思的思路: https://stackoverflow.com/questions/3838322/bash-read-write-file-descriptors-seek-to-start-of-file
- python可以直接打开fd,也能seek,c也能,但是借助外部程序的话,势必要把整个进程空间替换成外部程序,这样就回不来了
- 有时候,我们大可不必非要使用 &的方式访问文件描述符,直接使用 /proc/self/fd/8 可能更加方便,如:
- 当然,这样总是读第一行
为什么下面写法是不对的?
- 一个文件描述符不可能同时指向两个不同的文件,相同的文件打开两次也是要覆盖的;所以这里读打开是覆盖了写打开的,所以,最终是写不了的
- 所以,如果要读写同一个文件,最好使用不同的文件描述符分别打开文件