shell 的重定向分为两种:
输入重定向和输出重定向
;从字面上理解,
输入输出重定向就是 改变输入和输出的方向
;
那么,什么是输入输出方向? 标准的输入输出方向又是什么呢?
一般情况下,我们都是从键盘读取用户输入数据,然后再把数据拿到程序(如C语言程序、shell脚本程序)中使用,这就是
标准的输入方向,也就是从键盘到程序
;
反过来说,程序在运行后会产生数据,这些数据一般都是直接呈现到显示器上,这就是
标准的输出方向,也就是从程序到显示器
;
简而言之,其实
输入输出方向就是数据的流动方向
:
输入方向就是数据从哪里流向程序,数据默认从键盘流向程序,如果改变了它的方向,数据就从其他地方流入程序,这就是输入重定向;
输出方向就是数据从程序流向哪里,数据默认从程序流向显示器,如果改变了它的方向,数据就流向其他地方,这就是输出重定向;
硬件设备和文件描述符
计算机中的硬件设备有很多,常见的输入设备有键盘、鼠标、麦克风,输出设备有显示器、打印机等;不过在 linux 中,标准输入设备指的是键盘,标准输出设备指的是显示器;
在linux中一切皆文件,包括标准输入输出设备在内的所有计算机硬件都是文件;
为了表示和区分已经打开的文件,linux会给每个文件分配一个ID,这个ID是一个整数,称为
文件描述符
;
linux程序在执行任何形式的I/O操作时,都是在读取或者写入一个文件描述符;文件描述符只是一个和打开文件相关联的整数,它的背后可能是一个硬盘上的普通文件、FIFO、管道、终端等;
stdin、stdout、stderr 默认都是打开的,在重定向的过程中,0、1、2 这三个文件描述符可以直接使用;
输出重定向
输出重定向是指命令的结果不再输出到显示器上,而是输出到其他地方,一般是文件中;这样做的好处就是可以将命令的结果保存起来;bash支持的输出重定向符号如下所示:
类 型 | 符 号 | 作 用 |
---|---|---|
标准输出重定向 | command >file | 以覆盖的方式,把 command 的正确输出结果输出到 file 文件中 |
command >>file | 以追加的方式,把 command 的正确输出结果输出到 file 文件中 | |
标准错误输出重定向 | command 2>file | 以覆盖的方式,把 command 的错误信息输出到 file 文件中 |
command 2>>file | 以追加的方式,把 command 的错误信息输出到 file 文件中 | |
正确输出和错误信息同时保存 | command >file 2>&1 | 以覆盖的方式,把正确输出和错误信息同时保存到同一个文件(file)中 |
command >>file 2>&1 | 以追加的方式,把正确输出和错误信息同时保存到同一个文件(file)中 | |
command >file1 2>file2 | 以覆盖的方式,把正确的输出结果输出到 file1 文件中,把错误信息输出到 file2 文件中 | |
command >>file1 2>>file2 | 以追加的方式,把正确的输出结果输出到 file1 文件中,把错误信息输出到 file2 文件中 |
在输出重定向中,>代表的是覆盖,>>代表的是追加;
注意
:
输出重定向的完整写法是:
command fd>file
或者
command fd>>file
其中 fd 为文件描述符,默认为1,也就是标准输出文件;
fd为1时一般可以不写,但是为2时就必须要写上;
需要特别说明的是
fd和> 之间不能有空格
,否则shell 会解析失败;>和file之间的空格可有可无;
下面的例子将 echo 命令的输出结果以追加的方式写入到 demo.txt 文件中:
错误输出重定向举例:
命令正确执行是没有错误信息的,我们必须刻意地让命令执行出错,如下所示:
正确和错误信息分别保存到不同的文件:
ls -l >>out.log 2>>err.log
上面的命令将正确信息保存到 out.log,将错误信息保存到 err.log
here doc
与perl类似,shell 也支持here doc来定义字符串,其基本格式为:
command < < delimiter
document
delimiter
#delimeter为分隔符
下面的例子通过 here doc 将字符串写入到文件中:
上面的例子将16和17行的字符串通过 cat 命令写入到了 test.txt文件中
/dev/null 文件
如果既不想将命令的输出结果保存到文件,也不想输出到显示器上,那么可以将命令的所有结果重定向到 /dev/null文件中,如下所示:
ls -l &>/dev/null #注意要加&
可以把 /dev/null 当成 linux系统的垃圾箱,任何丢入垃圾箱的数据都会被丢弃,不能恢复;
输入重定向
输入重定向就是改变输入的方向,不再使用键盘作为命令输入的来源,而是使用文件作为命令的输入;
符号 | 说明 |
---|---|
command | 将 file 文件中的内容作为 command 的输入 |
command < | 从标准输入(键盘)中读取数据,直到遇见分界符 END 才停止(分界符可以是任意的字符串,用户自己定义) |
command file2 | 将 file1 作为 command 的输入,并将 command 的处理结果输出到 file2 |
和输出重定向类似,输入重定向的语法为:
fd<file
其中fd 是文件描述符,默认为0,也就是标准输入文件;
看下面例子,用 wc 命令来对文本进行统计,包括单词个数、行数、字节数,它的用法如下:
wc [选项] [文件名]
选项可为:
-c 统计字节数
-w 统计单词数
-l 统计行数
再来看下面的例子,
逐行读取文件的内容
:
这种写法叫做代码块重定向,也就是将一组命令同时重定向到一个文件;
再来看下面的例子,统计用户在终端输入的文本行数:
这里使用了 <<重定向符号,这个符号的作用是使用特定的分界符作为命令输入的结束标志,上面的例子中的结束标志为END;
<<之后的分界符可以自由定义,wc命令会一直等待用户输入,直至遇到分界符才结束读取;