侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

浅谈文件描述符1和2

2023-12-05 星期二 / 0 评论 / 0 点赞 / 73 阅读 / 4883 字

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

在linux系统中, 我们知道有 标准输入 , 标准输出 ,  和标准错误,  并且都分别对应着0, 1, 2

  这三个文件描述符, 在每个进程诞生之际,就已经随着伴随左右,通过以下命令就能看出来:

[root@iZ23pynfq19Z ~]# ll /proc/$$/fdtotal 0lrwx------ 1 root root 64 Dec 14 23:02 0 -> /dev/pts/1lrwx------ 1 root root 64 Dec 14 23:31 1 -> /dev/pts/1lrwx------ 1 root root 64 Dec 14 23:21 2 -> /dev/pts/1lrwx------ 1 root root 64 Dec 14 23:31 255 -> /dev/pts/1

从上图可以很清楚的看出来, 0, 1, 2都分别绑定到/dev/pts/1(根据实际情况来看), /dev/pts/1是我这边的终端设备文件, 正因为这样的绑定关系, 所以我们才能在屏幕中看到标准输出/标准错误, 

在系统方面, 这三个数字已经称为约定俗成的规定了, 而且从系统选择文件描述符的套路也能看出这点:

  系统在分配新的文件描述符时, 总是从最小并且未被使用开始.

所以从上面的种种因素中, 我们能够得出一个猜想, 如果我们改变文件描述符 1,2的指向, 是不是就能实现重定向符 ">" 的作用呢?  答案是肯定的!

[root@iZ23pynfq19Z ~]# touch 123       # 新建一个文件[root@iZ23pynfq19Z ~]# ls              # 在未改变标准输出的 ls 结果123[root@iZ23pynfq19Z ~]# exec 10>&1      # 用exec 将文件描述符1原有的绑定结果暂存到 文件描述符10 [root@iZ23pynfq19Z ~]# exec 1>stdout.log  # 用exec 将文件描述符1绑定到stdout.log[root@iZ23pynfq19Z ~]# ls     [root@iZ23pynfq19Z ~]# echo 123###  以上的命令均无输出 ### [root@iZ23pynfq19Z ~]# exec 1>&10      # 将文件描述符1 还原回来[root@iZ23pynfq19Z ~]# ls              # ls 命令结果出现123  stdout.log[root@iZ23pynfq19Z ~]# cat stdout.log   # 查看刚才绑定的文件, 里面的结果就是刚才 ls和echo的结果123stdout.log123

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

[root@iZ23pynfq19Z ~]# exec 10>&2[root@iZ23pynfq19Z ~]# exec 2>stderr.log### 分别敲如命令"ls" "echo asd"123  stderr.log  stdout.logasd

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

### 接着刚才的asd ###### 盲打 exec 2>&10 ###### 命令提示符什么都出现了 ### [root@iZ23pynfq19Z ~]# vim stderr.log  ### 以下为文件 stderr.log 的内容 不要搞混咯 ###[root@iZ23pynfq19Z ~]# ls[root@iZ23pynfq19Z ~]# ls[root@iZ23pynfq19Z ~]# echo asd[root@iZ23pynfq19Z ~]# asda-bash: asda: command not found[root@iZ23pynfq19Z ~]# ^G^G^Gexec 2>&10~                                                                                                                                                                                                                ~                                                                                                         ~                                                                                                         "stderr.log" 6L, 180C  

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

三种缓冲模式:

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

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

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

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

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

欢迎各位大牛指点教育, 转载请注明:https://my.oschina.net/u/2291453/blog/806102

广告 广告

评论区