从定义上来看,Linux重定向就是指修改原来默认的一些东西,对原来系统命令的默认执行方式进行改变,好比说简单的我不想看到在显示器的输出而是但愿输出到某一文件中就能够经过Linux重定向来进行这项工做。在进一步探索重定向以前,咱们先理解一下linux文件描述符。html
文件描述符理解为linux跟踪打开文件,而分配的一个数字,这个数字有点相似c语言操做文件时候的句柄,经过句柄就能够实现文件的读写操做。 用户能够自定义文件描述符范围是:3-num,这个最大数字,跟用户的:ulimit –n 定义数字有关系,不能超过最大值。java
linux启动后,会默认打开3个文件描述符,分别是:标准输入standard input 0,正确输出standard output 1,错误输出:error output 2,每一个文件有对应的文件描述符来方便咱们使用:linux
类型 | 文件描述符 | 默认状况 | 对应文件句柄位置 |
---|---|---|---|
标准输入(standard input) | 0 | 从键盘得到输入 | /proc/self/fd/0 |
标准输出(standard output) | 1 | 输出到屏幕(即控制台) | /proc/self/fd/1 |
错误输出(error output) | 2 | 输出到屏幕(即控制台) | /proc/self/fd/2 |
一般,一个命令执行过程以下:shell
先有一个输入:输入能够从键盘,也能够从文件获得;centos
命令执行完成:成功了,会把成功结果输出到屏幕:standard output默认是屏幕;bash
命令执行有错误:会把错误也输出到屏幕上面:standard error默认也是指的屏幕;post
因此咱们平时在执行shell命令中,都默认是从键盘得到输入,而且将结果输出到控制台上。可是咱们能够经过更改文件描述符默认的指向,从而实现输入输出的重定向。好比咱们将1指向文件,那么标准的输出就会输出到文件中。接下来咱们进一步的介绍Linux中的输入重定向和输出重定向。this
输出重定向的使用方式很简单,基本的一些命令格式以下:url
命令 | 介绍 |
---|---|
command >file | 把标准输出(stdout)重定向到 file 文件中; |
command 1>file | 同上; |
command >>file | 把 stdout 重定向到 file 文件中(追加); |
command 1>>file | 同上; |
command 2>file | 把标准错误(stderr)重定向到 file 文件中; |
command 2>>file | 把 stderr重定向到 file 文件中(追加); |
command >> file 2>&1 | 把 stdout 和 stderr 一块儿重定向到 file 文件中(追加); |
cmd > file 2>&1 | 把 stdout 和 stderr 一块儿重定向到 file 文件中; |
cmd >> file 2>&1 | 把 stdout 和 stderr 一块儿重定向到 file 文件中(追加); |
咱们使用>
或者>>
对输出进行重定向。符号的左边表示文件描述符,若是没有的话表示1,也就是标准输出,符号的右边能够是一个文件,也能够是一个输出设备。当使用>
时,会判断右边的文件存不存在,若是存在的话就先删除,而后建立一个新的文件,不存在的话则直接建立。可是当使用>>
进行追加时,则不会删除原来已经存在的文件。spa
格式:
command-line1 [1-n] > file或文件操做符或设备
这条命令意思是:将一条命令执行结果(标准输出,或者错误输出,原本都要打印到屏幕上面的) 重定向其它输出设备(文件,打开文件操做符,或打印机等等)1,2分别是标准输出,错误输出。
实例:
#查看文件内容,1.txt 2.txt (其中2.txt文件不存在) [root@sccprocddev02:/home/upro01]#cat 1.txt 2.txt this is a.txt cat: 2.txt: No such file or directory #标准输出与错误输出都显示在屏幕了, #如今须要把标准输出写入到1.log中 # 1>能够省略,表示标准输出 [root@sccprocddev02:/home/upro01]#cat 1.txt 2.txt 1>1.log cat: 2.txt: No such file or directory [root@sccprocddev02:/home/upro01]#cat 1.txt 2.txt >1.log cat: 2.txt: No such file or directory [root@sccprocddev02:/home/upro01]#cat 1.log this is a.txt #标准输出不输出到屏幕,输出到1.log中 #错误输出不输出到屏幕,输出到2.log中 [root@sccprocddev02:/home/upro01]#cat 1.txt 2.txt 1>1.log 2>2.log [root@sccprocddev02:/home/upro01]#cat 1.log 2.log this is a.txt cat: 2.txt: No such file or directory #将标准输出和错误输出分别追加到文件1.log和2.log中 “>>”追加操做符 #能够看到两个文件分别多出一行输出的内容 [root@sccprocddev02:/home/upro01]#cat 1.txt 2.txt 1>>1.log 2>>2.log [root@sccprocddev02:/home/upro01]#cat 1.log 2.log this is a.txt this is a.txt cat: 2.txt: No such file or directory cat: 2.txt: No such file or directory [root@sccprocddev02:/home/upro01]# 高级用法 #将错误输出信息关闭掉,控制台只打印了标准输出 [root@sccprocddev02:/home/upro01]#cat 1.txt 2.txt 2>&- this is a.txt [root@sccprocddev02:/home/upro01]#cat 1.txt 2.txt 2>/dev/null this is a.txt #&[n] 表明是已经存在的文件描述符,&1 表明输出 &2表明错误输出&-表明关闭与它绑定的描述符 #/dev/null 这个设备,是linux 中黑洞设备,什么信息只要输出给这个设备,都会给吃掉 #关闭全部输出 #关闭 1 ,2 文件描述符 [root@sccprocddev02:/home/upro01]#cat 1.txt 2.txt 1>&- 2>&- #将1,2 输出转发给/dev/null设备 [chengmo@centos5 shell]$ ls test.sh test1.sh 2>/dev/null 1>/dev/null [root@sccprocddev02:/home/upro01]#cat 1.txt 2.txt >/dev/null 2>&1 #将错误输出2绑定给正确输出1,而后将正确输出发送给 /dev/null设备 这种经常使用
#文件描述符前必须有个 &, 不然2>1就变成将错误输出输出到一个名为1的文件了
[root@sccprocddev02:/home/upro01]#cat 1.txt 2.txt &>/dev/null #& 表明全部文件描述符,该命令会将全部标准输出与错误输出输入到/dev/null文件
在理解了输出重定向以后,理解输入重定向就会容易得多。对输入重定向的基本命令以下:
命令 | 介绍 |
---|---|
command <filename | 以filename文件做为标准输入 |
command 0<filename | 同上 |
command <<delimiter | 从标准输入中读入,直到遇到delimiter分隔符 |
command < file >file2 | command命令以 file 文件做为标准输入(stdin),以 file2文件做为stdout; |
cat <>file | 以读写的方式打开 file; |
咱们使用<
对输入作重定向,若是符号左边没有写值,那么默认就是0。
格式:
command-line [n] <file或文件描述符&设备
命令默认从键盘得到的输入,使用输入重定向改为从文件,或者其它打开文件以及设备输入。执行这个命令,将标准输入0,与文件或设备绑定。将由它进行输入。
实例:
[root@sccprocddev02:/home/upro01]#cat > stdout.txt this is stdout.txt ^C [root@sccprocddev02:/home/upro01]#cat stdout.txt this is stdout.txt #这里使用ctrl+d 或者ctrl+c退出输入 #从标准输入[键盘]得到数据,而后输出给stdout.txt文件 [root@sccprocddev02:/home/upro01]#cat > stdout2.txt < stdout.txt [root@sccprocddev02:/home/upro01]#cat stdout2.txt this is stdout.txt #从stdout.txt得到输入数据,而后输出给文件catfile [root@sccprocddev02:/home/upro01]#cat > stdout3.txt << end > first line > second line > end [root@sccprocddev02:/home/upro01]#cat stdout3.txt first line second line #<< 这个连续两个小符号, 他表明的是[结束的输入字符]的意思。这样当空行输入end字符时,自动退出输入,不须要使用ctrl+d或者ctrl+c退出
前面的例子中咱们执行过以下一条命令
cat 1.txt 2.txt >/dev/null 2>&1
这条命令其实分为两命令,一个是>/dev/null
,另外一个是2>&1
。
>/dev/null
这条命令的做用是将标准输出1重定向到/dev/null中。/dev/null表明linux的空设备文件,全部往这个文件里面写入的内容都会丢失,俗称“黑洞”。那么执行了>/dev/null
以后,标准输出就会再也不存在,没有任何地方可以找到输出的内容。
2>&1
这条命令用到了重定向绑定,采用&能够将两个输出绑定在一块儿。这条命令的做用是错误输出将和标准输出同用一个文件描述符,说人话就是错误输出将会和标准输出输出到同一个地方。
linux在执行shell命令以前,就会肯定好全部的输入输出位置,而且从左到右依次执行重定向的命令,因此>/dev/null 2>&1
的做用就是让标准输出重定向到/dev/null中(丢弃标准输出),而后错误输出因为重用了标准输出的描述符,因此错误输出也被定向到了/dev/null中,错误输出一样也被丢弃了。执行了这条命令以后,该条shell命令将不会输出任何信息到控制台,也不会有任何信息输出到文件中。
注意:这里的>/dev/null 和 2>&1的顺序是不能写反的,2>&1 >/dev/null这样的写法结果将是:标准错误打印到屏幕,而标准输出不打印到屏幕。
咱们用一个表格来更好地说明这两条命令的区别:
命令 | 标准输出 | 错误输出 |
---|---|---|
>/dev/null 2>&1 | 丢弃 | 丢弃 |
2>&1 >/dev/null | 丢弃 | 屏幕 |
在工做中咱们经常会使用到重定向功能,好比在启动java项目时,由于咱们已经配置好了日志文件,因此咱们不想输出默认的nohup.out日志,那么咱们一般会使用以下命令
# nohup java -jar xxxx.jar >/dev/null 2>&1 &
格式:
exec 文件描述符[n] <或> file或文件描述符或设备
在上面讲的输入,输出重定向 将输入,输出绑定文件或设备后。只对当前那条指令是有效的。若是须要在绑定以后,接下来的全部命令都支持的话。就须要用exec命令
[root@sccprocddev02:/home/upro01]$ exec 6>&1 #将标准输出与fd 6绑定 [root@sccprocddev02:/home/upro01]$ ls /proc/self/fd/ 0 1 2 3 6 #出现文件描述符6 [root@sccprocddev02:/home/upro01]$ exec 1>6.txt #将接下来全部命令标准输出,绑定到6.txt文件(输出到该文件) [root@sccprocddev02:/home/upro01]$ ls -al #执行命令,发现什么都不返回了,由于标准输出已经输出到6.txt文件了 [root@sccprocddev02:/home/upro01]$ exec 1>&6 #恢复标准输出 [root@sccprocddev02:/home/upro01]$ exec 6>&- #关闭fd 6描述符 [root@centos5 ~]$ ls /proc/self/fd/ 0 1 2 3
说明:使用前先将标准输入保存到文件描述符6,这里说明下,文件描述符默认会打开0,1,2 还可使用自定义描述符 。而后对标准输出绑定到文件,接下来全部输出都会发生到文件。 使用完后,恢复标准的输出,关闭打开文件描述符6。
>&n 使用系统调用 dup2复制文件描述符 n 并把结果用做标准输出; <&n 标准输入复制自文件描述符 n; <&- 关闭标准输入(键盘); >&- 关闭标准输出; n<&- 表示将 n 号输入关闭; n>&- 表示将 n 号输出关闭; 上述全部形式均可之前导一个数字,此时创建的文件描述符由这个数字指定而不是缺省的 0 或 1。如: ... 2>file 运行一个命令并把错误输出(文件描述符 2)定向到 file。 ... 2>&1 运行一个命令并把它的标准输出和输出合并。(严格的说是经过复制文件描述符 1 来创建文件描述符 2 ,但效果一般是合并了两个流。) 我 们对 2>&1详细说明一下 :2>&1 也就是 FD2=FD1 ,这里并非说FD2 的值 等于FD1的值,由于 > 是改变送出的数据通道,也就是说把 FD2 的 “数据输出通道” 改成 FD1 的 “数据输出通道”。若是仅仅这样,这个改变好像没有什么做用,由于 FD2 的默认输出和 FD1的默认输出原本都是 monitor,同样的! 可是,当 FD1 是其余文件,甚至是其余 FD 时,这个就具备特殊的用途了。请你们务必理解这一点。 exec 1>outfilename # 打开文件outfilename做为stdout。 exec 2>errfilename # 打开文件 errfilename做为 stderr。 exec 0<&- # 关闭 FD0。 exec 1>&- # 关闭 FD1。 exec 5>&- # 关闭 FD5。
参考: