一、标准输入、标准输出和标准错误
对于
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、<
将后面的文件中的内容作为输入交给前头的命令来处理。这就是所谓的 “将输入重定向到文件”,文件内容为输入内容:
mcdx@ubuntu:~$ wc .vimrc
16 61 799 .vimrc
mcdx@ubuntu:~$ wc < .vimrc # 注意这两个命令的打印结果的区别
16 61 799
2、|
管道把标准输出传给后面的命令来处理,>
又把 cat
命令的标准输出放入后面的文件里了:
mcdx@ubuntu:~$ echo 'hello world' | cat > a
mcdx@ubuntu:~$ cat a
hello world
3、<
把 a
文件的内容作为 cat
要处理的数据即 cat
的标准输入,>
把前面的 cat
命令的标准输出放到后面的 b
文件中:
mcdx@ubuntu:~$ cat > b < a # 等同于 cat < a > b
mcdx@ubuntu:~$ cat b
hello world
4、对比“例 2”,|&
把标准输出和标准错误都传入后面的命令来处理:
mcdx@ubuntu:~$ cat a 晴空一鹤排云上
hello world
cat: 晴空一鹤排云上: 没有那个文件或目录
mcdx@ubuntu:~$ cat a 晴空一鹤排云上 |& cat
hello world
cat: 晴空一鹤排云上: 没有那个文件或目录
mcdx@ubuntu:~$ cat a 晴空一鹤排云上 |& cat > c
mcdx@ubuntu:~$ cat c
hello world
cat: 晴空一鹤排云上: 没有那个文件或目录
5、2>
将标准错误传入后面的文件,对比“例 4”,注意区别:
mcdx@ubuntu:~$ cat a 晴空一鹤排云上 2> c
hello world
mcdx@ubuntu:~$ cat c
cat: 晴空一鹤排云上: 没有那个文件或目录
6、如果想把标准输出和标准错误分别放俩文件中,可以这样:
mcdx@ubuntu:~$ cat a 晴空一鹤排云上 > d 2> f
mcdx@ubuntu:~$ cat d
hello world
mcdx@ubuntu:~$ cat f
cat: 晴空一鹤排云上: 没有那个文件或目录
7、关于 2>&1
1>&2
&>
:>
的用法:
# 将 cat 命令的标准输出重定向到 err 文件,标准错误保持不变,默认打印到终端
mcdx@ubuntu:~$ cat a 晴空一鹤排云上 > err
cat: 晴空一鹤排云上: 没有那个文件或目录
mcdx@ubuntu:~$ cat err
hello world
# 首先将 cat 命令的标准输出重定向到文件,然后将标准错误重定向为标准输出
# 此时标准输出去哪里,标准错误就去哪里
# 本来两者都应该打印到终端,现在都定向到了文件
mcdx@ubuntu:~$ cat a 晴空一鹤排云上 > err 2>&1
mcdx@ubuntu:~$ cat err
hello world
cat: 晴空一鹤排云上: 没有那个文件或目录
# 首先将 cat 命令的标准错误重定向到标准输出,此时两者都应该打印到终端
# 这就相当于 2>&1 没起作用,因为标准错误跟随标准输出,但标准输出没动
# 然后标准输出被重定向到 err 文件,标准错误被留在了终端
mcdx@ubuntu:~$ cat a 晴空一鹤排云上 2>&1 > err
cat: 晴空一鹤排云上: 没有那个文件或目录
mcdx@ubuntu:~$ cat err
hello world
# 同理,1>&2 将标准输出重定向到标准错误,结果一样
mcdx@ubuntu:~$ cat a 晴空一鹤排云上 2> err 1>&2
mcdx@ubuntu:~$ cat err
hello world
cat: 晴空一鹤排云上: 没有那个文件或目录
# 将 cat 命令的标准输出和标准错误分别都重定向到 err 文件
mcdx@ubuntu:~$ cat a 晴空一鹤排云上 &> err
mcdx@ubuntu:~$ cat err
hello world
cat: 晴空一鹤排云上: 没有那个文件或目录
# :> 清空文件内容
mcdx@ubuntu:~$ cat err
hello world
cat: 晴空一鹤排云上: 没有那个文件或目录
mcdx@ubuntu:~$ :> err
mcdx@ubuntu:~$ cat err
mcdx@ubuntu:~$