一、标准输入、标准输出和标准错误
对于 Linux 内核中的标准 I/O 库,stdio 提供了一个高效的缓存 I/O 流接口。一般情况下,每个程序在启动时都会有三个 stream(流)被预定义,一个用于输入,一个用于输出,还有一个用于打印诊断或者错误信息。对于 Linux 系统来说,读取标准输入和打印标准输出的地方默认情况下都是当前所使用的终端。
对应 shell 中常使用的三种标准 I/O 流:stdin stdout stderr
三个 stream 对应的文件描述符分别为:0 1 2
二、管道符
Linux 管道可以用于 Linux 程序之间,Linux 命令之间以及 Linux 程序和命令之间的通信。在 shell 中,管道符(pipeline)是 shell 编程中众多控制操作符里的一个,用来分隔一个或多个命令的序列。shell 编程中管道符号是竖杠符号 |(有时会用到 |& 符号),在 shell 中使用管道的格式如下,代表着 command1 的标准输出作为 command2 的标准输入使用,而 command2 的标准输出又作为 command3 的标准输入使用:
command1 | command2 | command3
三、重定向
命令
说明
command > file
将输出重定向到 file(把命令输出存入文件
command < file
将输入重定向到 file(把文件内容作为命令输入
command >> file
将输出以追加的方式重定向到 file
n> file
将文件描述符为 n 的内容重定向到 file(存入文件
n>> file
将文件描述符为 n 的文件以追加的方式重定向到 file
2>&1
将标准错误重定向到标准输出
1>&2
将标准输出重定向到标准错误
* 注意命令中的空格
一些例子
1、< 将后面的文件中的内容作为输入交给前头的命令来处理。这就是所谓的 “将输入重定向到文件”,文件内容为输入内容:
[email protected]:~$ wc .vimrc
16 61 799 .vimrc
[email protected]:~$ wc < .vimrc # 注意这两个命令的打印结果的区别
16 61 799
2、| 管道把标准输出传给后面的命令来处理,> 又把 cat 命令的标准输出放入后面的文件里了:
[email protected]:~$ echo 'hello world' | cat > a
[email protected]:~$ cat a
hello world
3、< 把 a 文件的内容作为 cat 要处理的数据即 cat 的标准输入,> 把前面的 cat 命令的标准输出放到后面的 b 文件中:
[email protected]:~$ cat > b < a # 等同于 cat < a > b
[email protected]:~$ cat b
hello world
4、对比“例 2”,|& 把标准输出和标准错误都传入后面的命令来处理:
[email protected]:~$ cat a 晴空一鹤排云上
hello world
cat: 晴空一鹤排云上: 没有那个文件或目录
[email protected]:~$ cat a 晴空一鹤排云上 |& cat
hello world
cat: 晴空一鹤排云上: 没有那个文件或目录
[email protected]:~$ cat a 晴空一鹤排云上 |& cat > c
[email protected]:~$ cat c
hello world
cat: 晴空一鹤排云上: 没有那个文件或目录
5、2> 将标准错误传入后面的文件,对比“例 4”,注意区别:
[email protected]:~$ cat a 晴空一鹤排云上 2> c
hello world
[email protected]:~$ cat c
cat: 晴空一鹤排云上: 没有那个文件或目录
6、如果想把标准输出和标准错误分别放俩文件中,可以这样:
[email protected]:~$ cat a 晴空一鹤排云上 > d 2> f
[email protected]:~$ cat d
hello world
[email protected]:~$ cat f
cat: 晴空一鹤排云上: 没有那个文件或目录
7、关于 2>&1 1>&2 &> :> 的用法:
# 将 cat 命令的标准输出重定向到 err 文件,标准错误保持不变,默认打印到终端
[email protected]:~$ cat a 晴空一鹤排云上 > err
cat: 晴空一鹤排云上: 没有那个文件或目录
[email protected]:~$ cat err
hello world
# 首先将 cat 命令的标准输出重定向到文件,然后将标准错误重定向为标准输出
# 此时标准输出去哪里,标准错误就去哪里
# 本来两者都应该打印到终端,现在都定向到了文件
[email protected]:~$ cat a 晴空一鹤排云上 > err 2>&1
[email protected]:~$ cat err
hello world
cat: 晴空一鹤排云上: 没有那个文件或目录
# 首先将 cat 命令的标准错误重定向到标准输出,此时两者都应该打印到终端
# 这就相当于 2>&1 没起作用,因为标准错误跟随标准输出,但标准输出没动
# 然后标准输出被重定向到 err 文件,标准错误被留在了终端
[email protected]:~$ cat a 晴空一鹤排云上 2>&1 > err
cat: 晴空一鹤排云上: 没有那个文件或目录
[email protected]:~$ cat err
hello world
# 同理,1>&2 将标准输出重定向到标准错误,结果一样
[email protected]:~$ cat a 晴空一鹤排云上 2> err 1>&2
[email protected]:~$ cat err
hello world
cat: 晴空一鹤排云上: 没有那个文件或目录
# 将 cat 命令的标准输出和标准错误分别都重定向到 err 文件
[email protected]:~$ cat a 晴空一鹤排云上 &> err
[email protected]:~$ cat err
hello world
cat: 晴空一鹤排云上: 没有那个文件或目录
# :> 清空文件内容
[email protected]:~$ cat err
hello world
cat: 晴空一鹤排云上: 没有那个文件或目录
[email protected]:~$ :> err
[email protected]:~$ cat err
[email protected]:~$