文件描述符(File Descriptor)
维基百科:文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。
Linux 的shell命令,可以通过文件描述符来引用一些文件,通常使用到的文件描述符为0,1,2,即:
文件 | 文件描述符 | 操作符 |
---|---|---|
输入文件—标准输入(stdin) | 0(默认是键盘,为0时是文件或者其他命令的输出) | < 或 << |
输出文件—标准输出 (stdout) | 1(默认是屏幕,为1时是文件) | >, >>, 1> 或 1>> |
错误输出文件—标准错误(stderr) | 2(默认是屏幕,为2时是文件) | 2> 或 2>> |
输出重定向
命令 | 描述 |
---|---|
Command > filename | 把标准输出重定向到一个新文件中 |
Command >> filename | 把标准输出重定向到一个文件(追加) |
Command > filename 2>&1 | 把标准输出和错误一起重定向到一个文件中 |
Command &> filename | 同上 |
Command >> filename 2>&1 | 把标准输出和错误一起重定向到一个文件中(追加) |
Command &>> filename | 同上 |
Command 2> filename | 把标准错误重定向到一个文件中 |
Command 2>> filename | 把标准错误重定向到一个文件中(追加) |
Command 1> filename 2> filename1 | 把标准输出和标准错误分别重定向到两个不同新的文件中 |
Command 1>> filename 2>> filename1 | 把标准输出和标准错误分别重定向到两个不同的文件中(追加) |
Command tee filename | 让标准输出在屏幕显示,同时重定向一个新的文件 |
Command | tee -i filename | 同上,但是不接受中断信号,只能Ctrl+D结束,不能用Ctrl+C |
Command | tee -a filename | 让标准输出在屏幕显示,同时重定向一个文件(追加) |
Command 2>&1 | tee filename | 让标准输出和标准错误在屏幕显示,重定向到一个新的文件中 |
Command 2>&1 | tee -a filename | 让标准输出和标准错误在屏幕显示,重定向到一个文件中(追加) |
1、Linux下还有一个特殊的文件/dev/null,它就像一个无底洞,所有重定向到它的信息都会消失得无影无踪。这一点非常有用,当我们不需要回显程序的所有信息时,就可以将输出重定向到/dev/null,例如:
ls xxx 1>/dev/null 2>/dev/null 或 ls >/dev/null 2>&1
2、使用操作符 > 或 >> 时,默认为标准输出1重定向, 所以 >filename 就是 1>filename 的省写,1与>之间不能有空格
3、>操作符,判断右边文件是否存在,若存在先删除,再创建新文件。不存则创建。 无论左边命令执行是否成功。右边文件都会变为空。
4、>>操作符,判断右边文件是否存在,若不存在,则先创建。以添加方式打开文件,会分配一个文件描述符[不特别指定,默认为1]然后,与左边对应的输出绑定。
5、管道 (“|”, pipe line),把上一个命令的 stdout 接到下一个命令的 stdin;
6、tee 命令的作用是在不影响原本 I/O 的情况下,将 stdout 复制一份到档案去;
例如:执行 who 命令,将命令的完整的输出重定向在文件中(/tmps/users),即:
who > /tmp/users
使用 cat 命令查看文件内容:
$ cat users
jason console Jan 11 09:05
jason ttys000 Jan 11 09:06
jason ttys001 Jan 11 09:06
jason ttys006 Jan 11 09:45
输入重定向
命令 | 描述 |
---|---|
Command < filename | Command 命令以 filename 文件作为标准输入 |
Command < filename > filename1 | Command以 filename 文件作为标准输入,以 filename1 作为标准输出 |
Command << delimiter | 从标准输入中读入,直到遇到 delimiter 分界符(以 delimiter 为开始/结束符) |
以上述who命令为例:
1、输入重定向到 users 文件,即:
$ wc -l < users
4
2、Here Document 是 Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序。 它的基本的形式如下:
command << delimiter
document
delimiter
它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command。
注意:
结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。
开始的delimiter前后的空格会被忽略掉。
例如:
$ wc -l << EOF
jason
jake
jacky
EOF
3 # 输出结果为 3 行
绑定重定向
命令 | 描述 |
---|---|
Command m>&n | 把输出到文件描述符m的信息重定向到文件描述符n上。如 exec 6>&1 |
Command m<&n | 把文件描述符n的信息输入到文件描述符m上。如 exec 6<&0 |
Command n<&- | 关闭输入文件描述符n。如 0<&-, <&- 关闭标准输入 |
Command n>&- | 关闭输出文件描述符n。如 1>&-, >&- 关闭标准输出,2>&- 关闭标准错误输出 |
0、1、2为shell保留文件描述符,可以自定义文件描述符,对其进行读写,用户自定义文件描述符用exec命令进行创建。用户可以自定义文件描述符围是:3~MAX,
这个最大数字,跟用户的:ulimit –n 定义数字有关系,不能超过最大值。
附:Mac下文件描述符的链接关系:
$ ls -al /dev/std* /dev/fd/*
crw--w---- 1 jason tty 16, 7 Jan 11 15:18 /dev/fd/0
crw--w---- 1 jason tty 16, 7 Jan 11 15:18 /dev/fd/1
crw--w---- 1 jason tty 16, 7 Jan 11 15:18 /dev/fd/2
lr-xr-xr-x 1 root wheel 0 Jan 11 09:05 /dev/stderr -> fd/2
lr-xr-xr-x 1 root wheel 0 Jan 11 09:05 /dev/stdin -> fd/0
lr-xr-xr-x 1 root wheel 0 Jan 11 09:05 /dev/stdout -> fd/1