首页服务器Web服务器 Bash中文件描述符的详细介绍

Bash中文件描述符的详细介绍

前言 Linux将所有内核对象当做文件来处理,系统用一个size_t类型来表示一个文件对象,比如对于文件描述符0就表示系统的标准输入设备STDIN,通常情况下STDIN的值为键盘,如read命令…

前言

Linux将所有内核对象当做文件来处理,系统用一个size_t类型来表示一个文件对象,比如对于文件描述符0就表示系统的标准输入设备STDIN,通常情况下STDIN的值为键盘,如read命令就默认从STDIN读取数据,当然STDIN的值是可以改变的,比如将其改成其他文件,这样的话想read等命令就会默认从相应的文件读取数据了。

简单地说,一个文件描述符可以和一个文件挂钩,一旦挂钩就可以通过取地址运算符&获得该文件的句柄,比如&0就可以获得STDIN设备在内存中的句柄(设备在系统中也被当做文件处理),可以这样理解,如果是一个shell中的普通变量var,可以通过$var的形式获得该变量所代表的值,而对于一个文件描述符fd,则可以通过&fd的形式获得文件描述符指向的文件的句柄,而这个句柄可以简单地理解成该文件的路径。

在 Shell 编程里经常会用到重定向操作, 它本质上是对文件描述符进行操作, 本文会对 Shell 脚本里的文件描述符做一个详细的介绍.

默认标准文件描述符

每个进程启动时默认都会有三个标准的文件描述符:

  • stdin 0 号描述符, 代表输入设备, 进程从它读入数据;
  • stdout 1 号描述符, 进程往其中写入数据;
  • stderr 2 号描述符, 进程会往其中写入错误信息;

这三个描述符默认是对应同一个 tty 设备, 这样我们便可以在终端中输入数据和获取进程的输出.

默认的文件描述符也是可以被替换的, 例如我们可以替换掉 stdout 到一个文件, 这样命令的输出就不是打印到终端, 而是被输出到文件中:

bash,文件描述符,linux,stdin

在上面的 demo 中, 我们先是通过 exec 1 > /tmp/stdout 把 stdout 指向了文件 /tmp/stdout, 紧接着我们执行了两条命令 ls 和 pwd, 可以看到此时终端已经没有了命令的输出. 当我们通过 exec 1 >&2 恢复 stdout 后, 可以发现文件 /tmp/stdout 里存储了之前命令的输出.

其中 exec 是一个 bash 内置命令, 不同于在终端中执行命令时会 fork 一个子进程, 通过 exec 执行的命令会直接修改当前的 shell 进程, 可以通过它执行命令来修改当前 shell 的 context.

如果你想使坏的话可以在别人的 ~/.bashrc 里加入 exec 1 > /tmp/stdout, 这样新开的所有的终端窗口里都看不到命令的输出, 要是因此被打概不负责 :) .

文件描述符的操作

Shell 中对文件描述符的操作由三部分组成: (Left, Operation, Right):

  • Left 可以是 0-9 的数字, 代表第 n 号文件描述符;
         Left 还可以为 &, 表示同时操作 stdout 和 stderr
  • Right 可以是文件名或 0-9 的数字, 当 Right 是数字时必须要加上 & 符号, 表示引用第 n 号文件描述符;
         Right 还可以为 &-, 此时表示关闭 Left 描述符, 例如 2<&- 表示关闭 stderr;
  • Operation 可以为 < 或 >;
         为 < 时表示以读模式复制 Right 到 Left, 此时如果没有指定 Left 的话, 则为默认值 0;
         当为 > 表示以写模式复制 Right 到 Left, 此时如果没有指定 Left 的话, 则为默认值 1;
         Operation 和 Left 之间不能有空格;
         当 Right 为文件名时, Operation 和 Right 可以有空格, 否则也不能有空格;

当存在多个文件描述符的操作时, 会按照从左往右的顺序依次执行. 例如通过命令 cmd 3>&1 1>&2 2>&3 3>&- 就可以交换 stdin 和 stdout.

我们通过下面的例子来验证上面的文件描述符交换是否生效:

  • 首先把默认的 stderr 重定向到文件 /tmp/stderr 中, 这样在终端中就不会看到错误输出了;
  • 当交换完 stderr 和 stdout 后, 我们就可以在 /tmp/stderr 文件中看到命令的正常输出了;

让我们来开始实验吧:

➜ test exec 2> /tmp/stderr➜ test lsa.txt➜ test ls 3>&1 1>&2 2>&3 3>&-➜ test cat /tmp/stderra.txt
本文来自网络,不代表1号站长-站长学院|资讯交流平台立场。转载请注明出处: https://www.1cn.cc/fwq/web/3781.html
上一篇Docker如何多步构建生成dubbo-admin镜像详解
下一篇 Linux中无法远程连接数据库问题的解决方法
admin

作者: admin

这里可以再内容模板定义一些文字和说明,也可以调用对应作者的简介!或者做一些网站的描述之类的文字或者HTML!

为您推荐

评论列表()

    联系我们

    联系我们

    0898-88888888

    在线咨询: QQ交谈

    邮箱: email@wangzhan.com

    工作时间:周一至周五,9:00-17:30,节假日休息

    关注微信
    微信扫一扫关注我们

    微信扫一扫关注我们

    关注微博
    返回顶部