输入輸出重定向从字面上看就是改变输入与输出的方向的意思,但是标准的输入与输出方向是什么呢?
我们先来解释输入设备和输出设备各有哪些。现在计算机的输入设备非常多,常见的有键盘、鼠标、麦克风、手写板等,常见的输出设备有显示器、投影仪、打印机等。不过,在 Linux 中,标准输入设备指的是键盘,标准输出设备指的是显示器。
在 Linux 中,所有的内容都是文件,计算机硬件也是文件,标准输入设备(键盘)和标准输出设备(显示器)也是文件。这些设备的设备文件名如下表所示。
设 备 | 设备文件名 | 文件描述符 | 类 型 |
---|---|---|---|
键盘 | /dev/stdin | 0 | 标准输入 |
显示器 | /dev/stdout | 1 | 标准输出 |
显示器 | /dev/stderr | 2 | 标准错误输出 |
Linux 是使用设备文件名来表示硬件的(比如 /dev/sda1 就代表第一块 SATA 硬盘的第一个主分区),但是键盘和显示器的设备文件名并不好记忆,我们用"0"、"1"、"2"来分别代表标准输入、标准输出和标准错误输出。
输出重定向指的是改变输出方向,不再输出到屏幕上,而是输出到文件他设备中;输入重定向则是指不再使用键盘作为输入设备,而是把文件的内容作为命令的输入。
输出重定向
输出重定向指的是把命令的结果不再输出到屏幕中,而是输出文件中。这样做最大的好处就是把命令结果保存到指定的文件中,当我们需要的时候可以随时调用。Bash 支持的输出重定向符号如表 2 所示。
类 型 | 符 号 | 作 用 |
---|---|---|
标准输出重定向 | 命令 > 文件 | 以覆盖的方式,把命令的正确输出输出到指定的文件或设备中 |
命令 >> 文件 | 以追加的方式,把命令的正确输出输出到指定的文件或设备中 | |
标准错误输出重定向 | 错误命令2 > 文件 | 以覆盖的方式,把命令的错误输出输出到指定的文件或设备中 |
错误命令2 >> 文件 | 以追加的方式,把命令的错误输出输出到指定的文件或设备中 | |
正确输出和错误输出同时保存 | 命令 > 文件2>&1 | 以捜盖的方式,把正确输出和错误输出都保存到同一个文件中 |
命令 >> 文件2>&1 | 以追加的方式,把正确输出和错误输出都保存到同一个文件中 | |
命令&>文件 | 以覆盖的方式,把正确输出和错误输出都保存到同一个文件中 | |
命令&>>文件 | 以追加的方式,把正确输出和错误输出都保存到同一个文件中 | |
命令>>文件1 2>>文件2 | 把正确的输出追加到文件1中,把错误的输出追加到文件2中 |
标准输出重定向
在输出重定向中,">"代表的是覆盖,">>"代表的是追加。举个例子:
[root@localhost ~]# ls -l > out.log #ls命令的输出并没有显示到屏幕上 [root@localhost ~]# cat out.log 总用量48 -rw-------. 1 root root 1168 4月10 21:49 anaconda-ks.cfg -rw-r--r--. 1 root root 24772 4月10 21:49 install.log -rw-r--r--. 1 root root 7690 4 月 10 21:49 install, log.syslog -rw-r--r--. 1 root root 0 6月 616:45 out.log drwxr-xr-x. 2 root root 4096 6月 610:39 sh #在当前目录中出现了outlog文件,在这个文件中保存着刚刚ls命令的输出 [root@localhost ~]# pwd > out.log #把pwd命令的输出也放入文件out.log中。也就是说,任何命令只要有输出,都可以使用输出重定向 [root@localhost ~]# cat out.log /root #在out.log文件中只有pwd命令的输出,而ls命令的被覆盖了
这就是">"的作用,任何有输出的命令都可以使用输出重定向把命令的输出保存到文件中。不过覆盖保存会把这个文件中的原有内容清空,所以追加重定向更加实用。
[root@localhost ~]# date >> out.log #把date命令的输出追加到outlog文件中 [root@localhost ~]# cat out.log /root 2013年10月17日星期四16:51:36 CST #把日期写入了文件中,但是并没有覆盖pwd命令的输出
标准错误输出重定向
如果想要把命令的错误输出保存到文件中,则用正确的输出重定向是不行的,比如:
[root@localhost ~]# ls test>> err.log ls:无法访问test:没有那个文件或目录
因为当前目录下没有 test 文件或目录,所以"ls test"命令报错了。不过命令的错误输出并没有保存到 err.log 文件中,而是输出到屏幕上。
这时需要这样来写这条命令:
[root@localhost ~]# ls test 2>> err.log
#错误输出重定向,错误输出没有输出到屏幕上,而是写入了err.log文件中
[root@localhost ~]# cat err.log
ls:无法访问test:没有那个文件或目录
2 代表错误输出,只有这样才能把命令的错误输出保存到指定的文件中。这里大家需要注意"2>>"一定不能有空格,否则会报错。
正确输出和错误输出同时保存
在实际的使用中,以上两种方法都不实用,因为正确的命令和错误的命令的保存方法是分开的。那么最常用的还是可以把正确输出和错误输出都保存下来的方法。命令如下:
[root@localhost ~]# ls >> out.log 2>&1 [root@localhost ~]# ls test &>>out.log #正确输出和错误输出都保存到out.log文件中 #这两种方法都可以使用,看个人习惯 [root@localhost ~]# cat out.log /root 2013年06月06日星期四16:51:36 CST anaconda-ks.cfg #第一条正确命令的输出追加保存了 err.log install.log install.log.syslog out.log sh ls:无法访问test:没有那个文件或目录 #第二条错误命令的输出也追加保存了
这两种把错误命令和正确命令写入同一个文件中的方法("命令>>文件2>&1"和"命令&>>文件")按照个人习惯都可以使用。不过我们还可以把正确输出和错误输出分开保存到不同的文件中,命令如下:
[root@localhost ~]# ls >>list.log 2>>err.log
如果这样写,则命令的正确输出会写入文件 list.log 中,而错误输出则会写入 err.log 文件中。笔者个人觉得,如果保存命令的执行结果,那么这种方法更加清晰。
如果我们并不想把命令的输出保存下来,也不想把命令的执行结果输出到屏幕上,干扰命令的执行,就可以把命令的所有执行结果放入 /dev/null 中。大家可以把 /dev/null 当成 Linux 系统的垃圾箱,任何放入垃圾箱的数据都会被丢弃,但是不能被恢复。命令如下:
[root@localhost ~]# ls &>/dev/null
输入重定向
输入重定向是改变输入的方向,不再使用键盘作为命令的输入,而是使用文件作为命令的输入。
首先,我们先讲解以下 wc 命令,命令格式如下:
[root@localhost ~]#wc [选项] [文件名]
选项:
- -c:统计字节数;
- -w:统计单词数;
- -l:统计行数;
例如:
[root@localhost ~]# wc hello, how are you? #使用Ctrl+D快捷键保存退出,在这里Ctrl+D不是退出登录的快捷键 2 4 20 #统计出刚刚输入的数据有2行、4个单词、20字节
wc 命令非常简单,可以统计我们通过键盘输入的数据。如果使用输入重定向符"<",则可以统计文件的内容。命令如下:
[root@localhost ~]# wc < anaconda-ks.cfg 49 117 1168 #anaconda>ks.cfg安装配置文件共有49行、117个单词、1168字节
其实,如果我们直接使用"wc anaconda-ks.cfg"命令是可以统计这个文件的数据的,不过这里只是演示一下输入重定向的作用。
那么,输入重定向在实际工作中有用处吗?输入重定向确实不如输出重定向常见,但是当我们需要使用 patch 命令打入补丁时,就会用到输入重定向。
还有一个输入重定向符号"<<",这个符号的作用是使用字符关键字作为命令输入的结束,而不使用 Ctrl+D 快捷键。命令如下:
[root@localhost ~] # wc << "hello" #定义关键字 >This is a test. >Welcome you to learn Linux >hello #当再碰到这个关键字时,命令结束,而不用Ctrl+D快捷键 2 9 43
"<<"之后的关键字可以自由定义,只要再碰到相同的关键字,两个关键字之间的内容将作为命令的输入(不包括关键字本身)。