Linux Shell重定向(输入输出重定向)精讲
那么,什么是输入输出方向呢?标准的输入输出方向又是什么呢?
一般情况下,我们都是从键盘读取用户输入的数据,然后再把数据拿到程序(C语言程序、Shell 脚本程序等)中使用;这就是标准的输入方向,也就是从键盘到程序。
反过来说,程序中也会产生数据,这些数据一般都是直接呈现到显示器上,这就是标准的输出方向,也就是从程序到显示器。
我们可以把观点提炼一下,其实输入输出方向就是数据的流动方向:
输入方向就是数据从哪里流向程序。数据默认从键盘流向程序,如果改变了它的方向,数据就从其它地方流入,这就是输入重定向。
输出方向就是数据从程序流向哪里。数据默认从程序流向显示器,如果改变了它的方向,数据就流向其它地方,这就是输出重定向。
硬件设备和文件描述符
计算机的硬件设备有很多,常见的输入设备有键盘、鼠标、麦克风、手写板等,输出设备有显示器、投影仪、打印机等。不过,在 Linux 中,标准输入设备指的是键盘,标准输出设备指的是显示器。Linux 中一切皆文件,包括标准输入设备(键盘)和标准输出设备(显示器)在内的所有计算机硬件都是文件。
为了表示和区分已经打开的文件,Linux 会给每个文件分配一个 ID,这个 ID 就是一个整数,被称为文件描述符(File Descriptor)。
文件描述符 | 文件名 | 类型 | 硬件 |
---|---|---|---|
0 | stdin | 标准输入文件 | 键盘 |
1 | stdout | 标准输出文件 | 显示器 |
2 | stderr | 标准错误输出文件 | 显示器 |
Linux 程序在执行任何形式的 I/O 操作时,都是在读取或者写入一个文件描述符。一个文件描述符只是一个和打开的文件相关联的整数,它的背后可能是一个硬盘上的普通文件、FIFO、管道、终端、键盘、显示器,甚是一个网络连接。
stdin、stdout、stderr 默认都是打开的,在重定向的过程中,0、1、2 这三个文件描述符可以直接使用。
Linux Shell 输出重定向
输出重定向是指令的结果不再输出到显示器上,而是输出到其它地方,一般是文件中。这样做的好处就是把令的结果保存起来,当我们需要的时候可以随时查询。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 >file 2>file | 【不】这两种写导致 file 被打开两次,引起资源竞争,所以 stdout 和 stderr 会互相覆盖,我们将在《结Linux文件描述符谈重定向,彻底理解重定向的本质》一节中深入剖析。 | |
command >>file 2>>file |
在输出重定向中,
>
代表的是覆盖,>>
代表的是追加。注意
输出重定向的完整写法其实是fd>file
或者fd>>file
,其中 fd 表示文件描述符,如果不写,默认为 1,也就是标准输出文件。当文件描述符为 1 时,一般都省略不写,如上表所示;当然,如果你愿意,也可以将
command >file
写作command 1>file
,但这样做是多此一举。当文件描述符为大于 1 的值时,比如 2,就必须写上。
需要重点说明的是,
fd
和>
之间不能有空格,否则 Shell 会解析失败;>
和file
之间的空格可有可无。为了保持一致,我习惯在>
两边都不加空格。下面的语句是一个反面教材:
echo "c.biancheng网站站点" rel="nofollow" /> echo "c.biancheng网站站点" rel="nofollow" /> #!/bin/bash for str in "C语言中文网" "http://c.biancheng网站站点" rel="nofollow" /> [c.biancheng网站站点" rel="nofollow" /> [c.biancheng网站站点" rel="nofollow" /> [c.biancheng网站站点" rel="nofollow" /> ls -l >>out.log 2>>err.log 这样一来,正确的输出结果会写入到 out.log,而错误的信息则会写入到 err.log。 /dev/null 文件 如果你既不想把令的输出结果保存到文件,也不想把令的输出结果显示到屏幕上,干扰令的执行,那么可以把令的所有结果重定向到 /dev/null 文件中。如下所示: ls -l &>/dev/null 大家可以把 /dev/null 当成 Linux 系统的垃圾箱,任何放入垃圾箱的数据都会被丢弃,不能恢复。 Linux Shell 输入重定向 表3:Bash 支持的输出重定向符号 符号 说明 command <file 将 file 文件中的内容作为 command 的输入。 command <<END 从标准输入(键盘)中读取数据,直到遇见分界符 END 才停止(分界符可以是任意的字符串,用户自己定义)。 command <file1 >file2 将 file1 作为 command 的输入,并将 command 的处理结果输出到 file2。 输入重定向举例 Linux wc 令可以用来对文本进行统计,包括单词个数、行数、字节数,它的用法如下: wc [选项] [文件名] 统计 readme.txt 文件中有多少行文本: [c.biancheng网站站点" rel="nofollow" /> #!/bin/bash while read str; do echo $str done <readme.txt [c.biancheng网站站点" rel="nofollow" />
和输出重定向类似,输入重定向的完整写法是fd<file
,其中 fd 表示文件描述符,如果不写,默认为 0,也就是标准输入文件。-c
选项统计字节数,-w
选项统计单词数,-l
选项统计行数。
C语言中文网
http://c.biancheng网站站点" rel="nofollow" />