linux文件描述符0 1 2,浅谈文件描述符1和2

在linux系统中, 我们知道有 标准输入 , 标准输出 , 和标准错误, 并且都分别对应着0, 1, 2这三个文件描述符, 在每个进程诞生之际,就已经随着伴随左右,通过以下命令就能看出来:

6c200a236ae45a287593fe84559b9849.png

从上图可以很清楚的看出来, 0, 1, 2都分别绑定到/dev/pts/1(根据实际情况来看), /dev/pts/1是我这边的终端设备文件, 正因为这样的绑定关系, 所以我们才能在屏幕中看到标准输出/标准错误, 在系统方面, 这三个数字已经称为约定俗成的规定了, 而且从系统选择文件描述符的套路也能看出这点。

系统在分配新的文件描述符时, 总是从最小并且未被使用开始.所以从上面的种种因素中, 我们能够得出一个猜想, 如果我们改变文件描述符 1,2的指向, 是不是就能实现重定向符 ">" 的作用呢? 答案是肯定的!

[root@361way test]# touch 123

[root@361way test]# ls # 在未改变标准输出的 ls 结果

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.com'

### 以上的命令均无输出 ###

[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.com

上面的实验执行的时候,注意以下几点:

1、执行exec 1>stdout.log后,此时会发现vim、nano、cat、less、more、ls 等涉及到标准输出,在屏幕上显示的命令都不能正常使用了;

2、不通过中间描述符10,是无法将原标准输出改回来的。不过也并不是执行这个修改后就会一直有问题,断开重新登录后或新开一个连接exec 1>stdout.log就失效了,因为新开时,0、1对应的可能是/dev/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

对于标准输出是这样, 对于标准错误也是这样, 如果对标准错误执行上面的实验, 会发现一个神奇的问题,怎么神奇, 看代码:

776fc96fbbfe0bfd4fdc0b4100570cd5.png

为什么会有这样的结果, 如果将错误输出重定向会导致这个结果, 那是不是就能说明我们看到的显示,其实都是标准错误的内容呢?

从文件stderr.log的输出, 我们已经能够确定, 我们登录终端看到的命令提示符什么的, 都是通过标准错误展示在我们面前, 这样似乎和我们的理解有点出入啊, 为什么不用标准输出呢, 多让人误解呀? 其实当我们了解到系统标准IO的三种缓冲模式就能知道为什么系统会通过标准错误展示:

三种缓冲模式:

全缓冲: 直到缓冲区被填满,才调用系统I/O函数, (一般是针对文件)

行缓冲: 遇到换行符就输出(标准输出)

无缓冲: 没有缓冲区,数据会立即读入或者输出到外存文件和设备上(标准错误)

一般来说, 无缓冲是最慢的, 但是存在即是合理, 它的作用就是为了让内容尽快的展示, 所以现在我们不难理解为什么命令提示符需要用标准错误输出了, 因为我们总不能等一个回车嘛~

如上面所说的, 我们可以通过改变文件描述符1/2的绑定, 来实现重定向, 实际上, 系统也是用这样类似的方法, 不过系统一般是用dup2/fcntl函数,这些又是一个大话题了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值