一般情况,我们的标准输入是键盘,标准输出是终端显示器;但是在很多情况,我们需要从文件中读取数据作为输入,然后将输出数据保存在文件中。这是我们就需要将标准输入从键盘重定向到文件,将标准输出重定向到文件,这个过程就是输入输出重定向。
输出重定向有两种方式
COMMAND > outputfile
COMMAND >> outputfile
其中>
和>>
是输出重定向的符号,前后必须有空格(这也是为什么要将大于号转义)。
>
和>>
的区别
>
示例:
[root@shell io_redirection]# pwd /mnt/io_redirection [root@shell io_redirection]# echo fsx.com fsx.com [root@shell io_redirection]# echo fsx.com > test.txt [root@shell io_redirection]# cat test.txt fsx.com
如果使用>
重定向数据到一个已经有内容的文件,会完全覆盖原来的内容
[root@shell io_redirection]# ls test.txt [root@shell io_redirection]# cat test.txt fsx.com [root@shell io_redirection]# echo qq > test.txt [root@shell io_redirection]# cat test.txt qq
有时候我们不希望覆盖源有数据,这时候就需要使用>>
来完成操作,我们称之为追加操作
[root@shell io_redirection]# ls test.txt [root@shell io_redirection]# cat test.txt qq [root@shell io_redirection]# echo fsx.com >> test.txt [root@shell io_redirection]# cat test.txt qq fsx.com //注意,不是紧跟追加,而是另起一行
输入重定向使用COMMAND < outputfile
来完成操作,将文件内容输出给命令。
[root@shell io_redirection]# cat < test.txt qq fsx.com [root@shell io_redirection]# cat < test.txt > test2.txt //同时输入重定向,输出重定向,将test.txt输入重定向到cat,再输出重定向到test2.txt中 [root@shell io_redirection]# ls test2.txt test.txt [root@shell io_redirection]# cat test2.txt qq fsx.com
使用格式:
COMMAND << marker //命令 << 标示符
data input //数据的输入
marker //提示符,成对出现
具体示例:
[root@shell io_redirection]# result=`bc << eof scale=3 var1=3.14 var2=2 var3=var1*var2 print var3 > eof` [root@shell io_redirection]# echo $result 6.28
在Linux系统中,将每个对象当作文件处理(Linux的核心思想,一切皆文件),包括输入输出的过程。
Linux用文件描述符来表识每一个文件对象。
文件描述符是一个非负整数,用来唯一标识会话中打开的文件。
每一个过程一次最多可以有 9 个文件描述符
LInux中shell提供三个文件描述符:
文件描述符 | 缩写 | 描述 |
---|---|---|
0 | STDIN | 标准输入 |
1 | STDOUT | 标准输出 |
2 | STDERR | 标准错误 |
标准输入输出重定向:COMMAND 1> outputfile
,COMMAND 0< outputfile
默认情况下,标准输入输出不需要指定文件描述符。但是如果对错误信息进行重定向是,就必须使用 2 来进行描述:COMMAND 2> outputfile
[root@shell io_redirection]# cat fsx //当我们试图访问一个不存在的文件,系统会输出标准错误到终端 cat: fsx: No such file or directory [root@shell io_redirection]# cat fsx 2> test4.txt //我们使用标准错误描述符,将错误信息重定向到一个文件中,则错误信息就被输出到该文件中 [root@shell io_redirection]# cat test4.txt cat: fsx: No such file or directory
这是我们进行错误捕获和错误处理的重要方式。
特别是,当我们的输出有正确输出,也有错误输出的时候,就可以使用文件描述符,将其分看,方便进一步处理
[fsx@shell ~]$ find /etc/ -name passwd* 1>find_out.txt 2>find_err.txt //将标准输出写入find_out.txt文件,将标准错误写入find_err.txt文件 [fsx@shell ~]$ cat find_out.txt /etc/pam.d/passwd /etc/passwd- /etc/passwd [fsx@shell ~]$ cat find_err.txt find: `/etc/lvm/cache': Permission denied find: `/etc/lvm/backup': Permission denied find: `/etc/lvm/archive': Permission denied find: `/etc/dhcp': Permission denied find: `/etc/audisp': Permission denied find: `/etc/selinux/targeted/modules/active': Permission denied find: `/etc/audit': Permission denied find: `/etc/pki/rsyslog': Permission denied find: `/etc/pki/CA/private': Permission denied find: `/etc/sudoers.d': Permission denied
shell脚本中输出重定向分为两种,一种是临时重定向,一种是永久重定向。
临时重定向:COMMAND >&文件描述符
[root@shell io_redirection]# cat test.sh #!/bin/bash echo "test error" >&2 //定义了一个错误信息,提供了我们自定义错误信息的能力 echo "normal output" //编写一个脚本文件test.sh,具体内容如上 [root@shell io_redirection]# bash test.sh //如果执行bash,都会显示,看起来没什么差别,这是因为标准错误也是通过标准输出的形式体现。 test error normal output [root@shell io_redirection]# bash test.sh 2>>errlog //如果我们将标准错误重定向到errlog文件中,则只显示标准输出 normal output [root@shell io_redirection]# cat errlog //查看文件中重定向的标准错误 test error
永久重定向:exec 文件描述符>文件名
将一个文件描述符值(1/2)定给一个文件。
[root@shell io_redirection]# cat test2.sh #!/bin/bash exec 1>testout.txt echo "normal output 1" echo "normal output 2" [root@shell io_redirection]# bash test2.sh [root@shell io_redirection]# cat testout.txt normal output 1 normal output 2 //这就将输出全部重定向到了文件中
这也可以同时定义标准错误和标准输出重定向
[root@shell io_redirection]# cat test3.sh #!/bin/bash exec 1>testout.txt exec 2>testerr.txt echo "normal output 1" >&1 echo "normal output 2" >&1 echo "error output 1" >&2 echo "error output 2" >&2 [root@shell io_redirection]# bash test3.sh [root@shell io_redirection]# cat testerr.txt error output 1 error output 2 [root@shell io_redirection]# cat testout.txt normal output 1 normal output 2
使用exec 0<文件名
可以实现脚本中的输入重定向。
[root@shell io_redirection]# cat input.sh #!/bin/bash exec 0< testerr.txt //使用exec实现输入重定向,将testerr.txt作为输入 count=1 //定义一个变量count,用来遍历testerr.txt while read line //循环遍历输入的每一行 do echo "line $count: $line" //输出,"line 行号:每行内容" count=$[count+1] //count自增,实现遍历每行 done [root@shell io_redirection]# bash input.sh //查看输出结果 line 1: error output 1 line 2: error output 2
在shell中,将一个命令的输出,重定向到另一个命名的输入,就需要用到管道。数据通过管道在两个命令中实现了传递。具体格式:
COMMAND1 | COMMAND2
ps -aux | less
就是将ps -aux的输出,传递给less就可以实现分页查看
[root@shell io_redirection]# ps -axu | grep bash Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ root 1018 0.0 0.3 108304 1944 pts/0 Ss 21:47 0:00 -bash root 1033 0.0 0.3 108304 1896 pts/1 Ss+ 21:47 0:00 -bash root 1369 0.0 0.1 103244 832 pts/0 S+ 23:30 0:00 grep bash //将ps命令的输出传递给grep命令,实现过滤出bash相关的进程信息
如果我们使用
ps -aux > psfile
less < psfile
这样也可以实现ps -aux | less的功能,但是这样1,效率不高;2,内核开销大
管道前后命令是同时进行的,不占用文件或者缓冲器,性能大大提高。
有没有一个即可以输出到终端,又实现重定向?即一个输入,两个输出?
[root@shell io_redirection]# date |tee date.txt Tue Apr 10 23:35:06 EDT 2018 [root@shell io_redirection]# cat date.txt Tue Apr 10 23:35:06 EDT 2018
这就是tee
命令,tee
命令的实现是管道和文件输入输出重定向的同时利用