I/O重定向允许我们将命令的输入和输出重定向或追加到文件中。
在linux中,由于标准输入(/dev/stdin)、标准输出(/dev/stdout)、标准错误(/dev/stderr)本质上都是一个文件,这三个文件用于处理系统的输入输出以及错误,而在linux系统中,这三个设备文件对应的文件描述符分别为0、1、2,可以通过这些文件描述符将终端的标准输入作为命令的输入和标准输出作为命令的输出。比如下面命令,将控制台输入的东西传入到文件中。
[root@localhost opt]# cat > file.txt
ls
hello
word
^C
[root@localhost opt]# cat file.txt
ls
hello
word
输出包括两种类型:
程序的正常结果。被称为标准输出 stdout
。
异常状态、错误信息。被称为标准错误 stderr
。
输入主要指程序从标准输入stdin
中获取输入。默认情况下,标准输入与键盘相连接。
默认情况下,stdout
和stderr
都被链接到屏幕上,而不是保存到文件中。重定向允许我们改变输出的去向和输入的来源。
>
重定向操作符会覆盖目标文件。如果要追加内容,我们可以使用>>
重定向操作符。比如使用重定向操作符将ls
命令的输出到ls-output.txt
文件中,而不是屏幕上。
ls -l /usr/bin > ls-output.txt
ls -l /bin/usr 2> ls-error.txt
重定向标准输出和标准错误到同一文件中,共有两种方式可以实现。
(1)传统方法,它适用于老版本的shell
:
ls -l /bin/usr > ls-output.txt 2>&1
首先将stdout
重定向到ls-output.txt
文件,然后用2>&1
的符号将文件描述符为2的stderr
重定向到文件描述符为1的stdout
中。
注意重定向的顺序,重定向stderr
必须总是写在在重定向stdout
之后。
cmd >a 2>a 和 cmd >a 2>&1 为什么不同?
cmd >a 2>a :stdout和stderr都直接送往文件 a ,a文件会被打开两遍,由此导致stdout和stderr互相覆盖。
cmd >a 2>&1 :stdout直接送往文件a ,stderr是继承了FD1的管道之后,再被送往文件a 。a文件只被打开一遍,就是FD1
将其打开。
他们的不同点在于:
cmd >a 2>a 相当于使用了两个互相竞争使用文件a的管道;
而cmd >a 2>&1 只使用了一个管道,但在其源头已经包括了stdout和stderr。
从IO效率上来讲,cmd >a 2>&1的效率应该更高!
(2)最近版本的bash
提供了第二种方法,该方法让执行这种组合重定向更精简。
ls -l /bin/usr &> ls-output.txt
你仍然可以使用>>
进行追加操作。
在 linux 中有一个被称为黑洞的设备文件(/dev/null),所有导入它的数据都将被吞噬。/dev/null,或称空设备,是一个特殊的设备文件,它通常被用于丢弃不需要的输出流,或作为用于输入流的空文件。类似于windows中会自动清理垃圾桶。
ls -l /bin/usr 2> /dev/null
还有<
重定向操作符,我们可以将stdin
的来源从键盘改为文件。
cat < sample.txt
使用管道操作符|
,一个命令的stout
可以通过管道进入另一个命令的stdin
,less
就是一个例子:
ls -l /usr/bin | less
tee
命令读取stdin
并将其重定向到多个输出。比如到stdout
和一个或多个文件中。比如如下命令将输出重定向到文件,也将信息打印在终端。
echo 'hello' | tee hello
exec命令 用于调用并执行指令的命令。exec命令通常用在shell脚本程序中,可以调用其他的命令。如果在当前终端中使用命令,则当指定的命令执行完毕后会立即退出终端。
[root@localhost ~]# exec echo hell
hell
连接断开
将标准输出重定向到文件file.txt中
exec 1>file.txt
此时执行ls命令,输出的内容不会出现在屏幕上,而是输出到了file.txt文件中 ls
如果执行了上述命令,此终端将不再有输出。关闭掉此shell,重启一个即可。