linux⽂件描述符012,浅谈⽂件描述符1和2
在linux系统中, 我们知道有 标准输⼊ , 标准输出 , 和标准错误, 并且都分别对应着0, 1, 2这三个⽂件描述符, 在每个进程诞⽣之际,就已经随着伴随左右,通过以下命令就能看出来:
从上图可以很清楚的看出来, 0, 1, 2都分别绑定到/dev/pts/1(根据实际情况来看), /dev/pts/1是我这边的终端设备⽂件, 正因为这样的绑定关系, 所以我们才能在屏幕中看到标准输出/标准错误, 在系统⽅⾯, 这三个数字已经称为约定俗成的规定了, ⽽且从系统选择⽂件描述符的套路也能看出这点。
系统在分配新的⽂件描述符时, 总是从最⼩并且未被使⽤开始.所以从上⾯的种种因素中, 我们能够得出⼀个猜想, 如果我们改变⽂件描述符1,2的指向, 是不是就能实现重定向符 ">" 的作⽤呢? 答案是肯定的!
[root@361way test]# touch 123
[root@361way test]# ls # 在未改变标准输出的 ls 结果
linux重定向
123
[root@361way test]# exec 10>&1 # ⽤exec 将⽂件描述符1原有的绑定结果暂存到 ⽂件描述符10
[root@361way test]# exec 1>stdout.log # ⽤exec 将⽂件描述符1绑定到stdout.log
[root@361way test]# ll /proc/$$/fd
[root@361way test]# echo 'www.361way'
### 以上的命令均⽆输出 ###
[root@361way test]# cat stdout.log # 这个有⼀个标准错误出现,这个提⽰很有意思。
cat: stdout.log: input file is output file
[root@361way test]# exec 1>&10 # 将⽂件描述符1 还原回来
[root@361way test]# ls
123 stdout.log
[root@361way test]# cat stdout.log # 查看刚才绑定的⽂件, ⾥⾯的结果就是刚才 ls和echo的结果
total 0
lrwx------ 1 root root 64 Aug 16 15:42 0 -> /dev/pts/1
l-wx------ 1 root root 64 Aug 16 15:42 1 -> /tmp/test/stdout.log # 对应上⾯的exec 1>stdout.log
lrwx------ 1 root root 64 Aug 16 15:44 10 -> /dev/pts/1
lrwx------ 1 root root 64 Aug 16 15:42 2 -> /dev/pts/1
lrwx------ 1 root root 64 Aug 16 15:44 255 -> /dev/pts/1
www.361way
上⾯的实验执⾏的时候,注意以下⼏点:
1、执⾏exec 1>stdout.log后,此时会发现vim、nano、cat、less、more、ls 等涉及到标准输出,在屏幕上显⽰的命令都不能正常使⽤了;
2、不通过中间描述符10,是⽆法将原标准输出改回来的。不过也并不是执⾏这个修改后就会⼀直有问题,断开重新登录后或新开⼀个连接exec 1>stdout.log就失效了,因为新开时,0、1对应的可能是/de
v/pts/2或/dev/pts/3 ;
3、/proc/$$/fd下的0、1、10等,是⽆法通过ln命令链接到/dev/pts/num的,也⽆法随意进⾏删除 。
[root@361way fd]# pwd
/proc/48226/fd
[root@361way fd]# ll
total 0
lrwx------ 1 root root 64 Aug 16 15:55 0 -> /dev/pts/1
lrwx------ 1 root root 64 Aug 16 15:55 1 -> /dev/pts/1
lrwx------ 1 root root 64 Aug 16 15:56 10 -> /dev/pts/1
lrwx------ 1 root root 64 Aug 16 15:55 2 -> /dev/pts/1
lrwx------ 1 root root 64 Aug 16 15:55 255 -> /dev/pts/1
[root@361way fd]# pwd
/proc/48226/fd
[root@361way fd]# ln -s /dev/pts/1 100
ln: failed to create symbolic link ‘100’: No such file or directory
[root@361way fd]# rm -rf 10
rm: cannot remove ‘10’: Operation not permitted
对于标准输出是这样, 对于标准错误也是这样, 如果对标准错误执⾏上⾯的实验, 会发现⼀个神奇的问题,怎么神奇, 看代码:
为什么会有这样的结果, 如果将错误输出重定向会导致这个结果, 那是不是就能说明我们看到的显⽰,其实都是标准错误的内容呢?
从⽂件stderr.log的输出, 我们已经能够确定, 我们登录终端看到的命令提⽰符什么的, 都是通过标准错误展⽰在我们⾯前, 这样似乎和我们的理解有点出⼊啊, 为什么不⽤标准输出呢, 多让⼈误解呀? 其实当我们了解到系统标准IO的三种缓冲模式就能知道为什么系统会通过标准错误展⽰:
三种缓冲模式:
全缓冲: 直到缓冲区被填满,才调⽤系统I/O函数, (⼀般是针对⽂件)
⾏缓冲: 遇到换⾏符就输出(标准输出)
⽆缓冲: 没有缓冲区,数据会⽴即读⼊或者输出到外存⽂件和设备上(标准错误)
⼀般来说, ⽆缓冲是最慢的, 但是存在即是合理, 它的作⽤就是为了让内容尽快的展⽰, 所以现在我们不难理解为什么命令提⽰符需要⽤标准错误输出了, 因为我们总不能等⼀个回车嘛~
如上⾯所说的, 我们可以通过改变⽂件描述符1/2的绑定, 来实现重定向, 实际上, 系统也是⽤这样类似的⽅法, 不过系统⼀般是⽤dup2/fcntl 函数,这些⼜是⼀个⼤话题了

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。