Linux——管道与重定向
参考资料:
重定向标准I/O
Linux shell(比如Bash)接收或发送序列和字符串流形式的输入或输出。每个字符都独立于与之相邻的字符。字符没有被组织成结构化记录或固定大小的块。不管实际的字符串流进入或来自文件、键盘、显示窗口或其他 I/O 设备,都使用文件 I/O 技术来访问流。Linux shell 使用 3 种标准的 I/O 流,每种流都与一个文件描述符相关联:
- stdout 是标准输出流,它显示来自命令的输出,默认输出显示到终端。它的文件描述符为 1。
- stderr 是标准错误流,它显示来自命令的错误输出,默认输出显示到终端。它的文件描述符为 2。
- stdin 是标准输入流,它为命令提供输入。它的文件描述符为 0。
输出重定向
将输出重定向到文件有两种方法:
n> 将输出从文件描述符 n 重定向到文件。必须具有该文件的写权限。如果该文件不存在,将创建它。如果该文件已经存在,通常将覆盖所有现有内容,并且没有任何警告。
n>> 将输出从文件描述符 n 重定向到一个文件中。这里也一样要求具有该文件的写权限。如果该文件不存在,将创建它。如果该文件已经存在,输出将附加到现有的内容后面。
直观的表述如下:
-
1> 表示标准输出重定向,覆盖
-
1>> 表示标准输出重定向,追加
-
2> 表示标准错误输出重定向,覆盖
-
2>> 表示标准错误输出重定向,追加
其中默认缺省表示标准输出。使用 n>的输出重定向通常覆盖现有的文件。可以使用 set
内置控件的 noclobber
选项对此进行控制。如果该选项已经设置,您可以使用 n>| 覆盖它
另外,当我们使用 ">" 重定向符来重定向输出结果时,目标文件总是从开头被重写。 所以例如我们 ls 命令没有产生运行结果,只有错误信息,但重定向操作开始重写文件,然后由于错误而停止,导致文件内容删除。因此,利用这个特点,如果我们需要删除一个文件内容,或者创建一个新的空文件的时候,我们完全可以使用如下技巧
zyzhang@zyzhang-Ubuntu:~$ > output.txt
在某些情况下,我们可能想要将标准输出和标准错误都重定向到一个文件中。这通常为自动进程或后台作业而执行的,以便以后可以查看输出。使用 &> 或 &>> 同时将标准输出和标准错误重定向到同一个文件中。
zyzhang@zyzhang-Ubuntu:~$ ls -l /bin/usr &> output.txt
另一种方法是,首先重定向文件描述符 n,然后使用 m>&n 或 m>>&n 将文件描述符 m 重定向到同一个文件。例如,
command >output.txt 2>&1
首先重定向标准输出到文件output.txt文件中,然后重定向文件描述符2(标准错误)到文件描述符1(标准输出)使用表示法 2>&1。
注意:重定向的顺序安排非常重要。标准错误的重定向必须总是出现在标准输出重定向之后,要不然它不起作用。上面的例子,
>output.txt 2>&1
重定向标准错误到文件 output.txt,但是如果命令顺序改为:
2>&1 >ls-output.txt
则标准错误定向到屏幕。
有时候,我们想忽略标准输出或标准错误,为此,将选择的流重定向到空文件 /dev/null,这个文件是系统设备,叫做位存储桶,它可以 接受输入,并且对输入不做任何处理。
zyzhang@zyzhang-Ubuntu:~$ ls -l /bin/usr 2> /dev/null
输入重定向
cat - 连接文件
cat 命令读取一个或多个文件,然后复制它们到标准输出,就像这样:
cat [file]
在大多数情况下,我们可以认为 cat 命令相似于 DOS 中的 TYPE 命令。你可以使用 cat 来显示文件而没有分页,例如:
zyzhang@zyzhang-Ubuntu:~$ cat ls-output.txt
将会显示文件 ls-output.txt 的内容。cat 经常被用来显示简短的文本文件。因为 cat 可以 接受不只一个文件作为参数,所以它也可以用来把文件连接在一起。
我们试着做些其他的工作。 如果我们输入不带参数的"cat"命令,会发生什么呢:
zyzhang@zyzhang-Ubuntu:~$ cat
没有发生任何事情,它只是坐在那里,好像挂掉了一样。看起来是那样,但是它正在做它该做的事情:
如果 cat 没有给出任何参数,它会从标准输入读入数据,因为标准输入,默认情况下,连接到键盘。 它正在等待我们输入数据!试试这个:
zyzhang@zyzhang-Ubuntu:~$ cat The quick brown fox jumped over the lazy dog.
下一步,输入 Ctrl-d(按住 Ctrl 键同时按下"d"),来告诉 cat,在标准输入中, 它已经到达文件末尾(EOF):
zyzhang@zyzhang-Ubuntu:~$ cat The quick brown fox jumped over the lazy dog.
由于文件名参数的缺席,cat 复制标准输入到标准输出,所以我们看到文本行重复出现。 我们可以使用这种行为来创建简短的文本文件。比方说,我们想创建一个叫做"lazy_dog.txt" 的文件,这个文件包含例子中的文本。我们这样做:
zyzhang@zyzhang-Ubuntu:~$ cat > lazy_dog.txt The quick brown fox jumped over the lazy dog.
输入命令,其后输入要放入文件中的文本。记住,最后输入 Ctrl-d。通过使用这个命令,我们 实现了世界上最低能的文字处理器!看一下运行结果,我们使用 cat 来复制文件内容到 标准输出:
zyzhang@zyzhang-Ubuntu:~$ cat lazy_dog.txt The quick brown fox jumped over the lazy dog.
现在我们知道怎讲接受标准输入,除了文件名参数,让我们试着重定向标准输入:
zyzhang@zyzhang-Ubuntu:~$ cat < lazy_dog.txt The quick brown fox jumped over the lazy dog.
使用“<”重定向操作符,我们把标准输入源从键盘改到文件 lazy_dog.tx。我们看到结果 和传递单个文件名作为参数的执行结果一样。把这和传递一个文件名参数作比较,尤其没有意义, 但它是用来说明把一个文件作为标准输入源。
┆ 凉 ┆ 暖 ┆ 降 ┆ 等 ┆ 幸 ┆ 我 ┆ 我 ┆ 里 ┆ 将 ┆ ┆ 可 ┆ 有 ┆ 谦 ┆ 戮 ┆ 那 ┆ ┆ 大 ┆ ┆ 始 ┆ 然 ┆
┆ 薄 ┆ 一 ┆ 临 ┆ 你 ┆ 的 ┆ 还 ┆ 没 ┆ ┆ 来 ┆ ┆ 是 ┆ 来 ┆ 逊 ┆ 没 ┆ 些 ┆ ┆ 雁 ┆ ┆ 终 ┆ 而 ┆
┆ ┆ 暖 ┆ ┆ 如 ┆ 地 ┆ 站 ┆ 有 ┆ ┆ 也 ┆ ┆ 我 ┆ ┆ 的 ┆ 有 ┆ 精 ┆ ┆ 也 ┆ ┆ 没 ┆ 你 ┆
┆ ┆ 这 ┆ ┆ 试 ┆ 方 ┆ 在 ┆ 逃 ┆ ┆ 会 ┆ ┆ 在 ┆ ┆ 清 ┆ 来 ┆ 准 ┆ ┆ 没 ┆ ┆ 有 ┆ 没 ┆
┆ ┆ 生 ┆ ┆ 探 ┆ ┆ 最 ┆ 避 ┆ ┆ 在 ┆ ┆ 这 ┆ ┆ 晨 ┆ ┆ 的 ┆ ┆ 有 ┆ ┆ 来 ┆ 有 ┆
┆ ┆ 之 ┆ ┆ 般 ┆ ┆ 不 ┆ ┆ ┆ 这 ┆ ┆ 里 ┆ ┆ 没 ┆ ┆ 杀 ┆ ┆ 来 ┆ ┆ ┆ 来 ┆