我们可以简单的理解一个程序由简单的两个部分组成

 程序=指令+数据


 而数据在处理时又会被读入或者输出

 读入数据称为: Input

 输出数据称为: Output

 Input/Output 简称为I/O


Linux给程序提供三种I/O设备

    标准输入( STDIN)- 0 默认接受来自键盘的输入

    标准输出( STDOUT)- 1 默认输出到终端窗口

    标准错误( STDERR)- 2 默认输出到终端窗口


上面描述了Linux中的三个默认的输入输出位置

既然是要聊聊重定向,就是要改变默认输入输出位置



重定向可以分为输出重定向和输入重定向


输出重定向

   先说说输出重定向,输出重定向我们先简单的理解为将输出到屏幕的信息输出到其他终端或文件。

输出重定向还可以细分为标准输出重定向,标准错误重定向,覆盖重定向,追加重定向等

 


标准输出覆盖重定向符号 >

 

STDOUT重定向到文件(覆盖的方式),只将标准输出重定向到文件,标准错误不会重定向到文件。每次重定向标准输出,都会将上次的数据覆盖,此种重定向称为覆盖重定向。

比如:[root@cos72 ~]# ls > outfile

 

使用set -CC大写)命令禁止对已经存在的文件使用覆盖重定向,在这种禁用的情况下,如果需要强制覆盖输出,则使用>|

比如:[root@cos72 ~]# ll >| outfile

 

使用set +CC大写)命令启用对已经存在的文件使用覆盖重定向

 


 

标准输出追加重定向符号 >>

 

STDOUT重定向到文件(追加的方式),只将标准输出重定向到文件,标准错误不会重定向到文件。此种重定向为追加重定向,原有数据不会被覆盖。

ls >> /home/outfile.log

 


 

标准错误覆盖重定向符号 2>

 

STDERR重定向到文件(覆盖的方式),只将标准错误重定向到文件,即使有标准输出,也不会重定向到文件,比如

ls 一个不存在的文件   2> errorout.log

 


 

标准错误追加重定向符号 2>>

追加重定向彼标准错误输出。

 


将标准输出和标准错误重定向到不同的文件

将标准输出重定向到a,将标准错误重定向到b

命令 > a 2> b

 

将标准输出和标准错误都重定向到同一个文件使用如下符号

&>

 

&>是将标准输出和标准错误都覆盖重定向到某个文件

 

并没有&>>这种写法,这种写法不代表将标准输出和标准错误都追加重定向到某个文件

 

例子:将标准输出和标准错误同时输出到io.out

[root@cos72 ~]# ls /var &> io.out

 

还有另外两种写法

cmd [>|>>] file 2>&1

cmd [2>|2>>] file 1>&2

 

cmd > file 2>&1

表示将‘标准错误’结合到‘标准输出’的输出文件(&1代表标准输出的输出通道,即前面的>,这种情况没有2>>&1的写法,到底是追加重定向还是覆盖重定向,取决于前面的标准输出是否追加,也就是说,如果想要使用追加的方式,需要这样使用:cmd >> file 2>&1

注意:在使用 2>&1这种方式时,前面必须定义了标准输出重定向的位置。

 

cmd 2> file 1>&2

表示将‘标准输出’结合到‘标准错误’的输出文件(&2代表标准错误的输出通道,即前面的2>,这种情况没有1>>&2的写法,到底是追加重定向还是覆盖重定向,取决于前面的标准错误是否追加,也就是说,如果想要使用追加的方式,需要这样使用:cmd 2>> file 1>&2

注意:在使用 1>&2这种方式时,前面必须定义了标准错误重定向的位置。

 

注意根据情况使用,如果2>&1 1>&2的情况搞混了会出现没有任何输出被重定向的情况

比如:如果使用   cmd > outfile 1>&2

就无法将任何 标准输出 标准错误 重定向到outfile中,因为这种用法是错误的。


 


输入重定向

   标准输入重定向可以理解为本来应该通过键盘输入得到的信息,现在不通过手动敲键盘输入了,而是将别的文件内容或文本重定向到标准输入,代替手动敲击键盘的动作。

    

    标准输入重定向符号 < 

    < 的右边跟文件路径,会把文件内容当做标准输入重定向到指向的目标

    例如

                    # cat < /etc/issue

 

    或者

                    #grep linuxcast < /etc/passwd



多行标准输入重定向符号<<

可以理解为将即将输入的多行标准输入一次性重定向到另一个标准输入

 

即将输入的内容经常用EOFEND标记,也可以使用其他的进行标记。

 

例如如下命令,将如下4行命令复制,直接粘贴到命令行执行,表示将两个EOF之间的内容作为  标准输入的内容,一次性的重定向到cat的标准输入,而不是一行一行的重定向到cat的标准输入,相当于我们不用手动通过键盘输入cat要求我们输入的标准输入内容,而是直接将EOF中间的文本当做标准输入,一次性多行重定向传递给了cat

cat << EOF

aaaaaa

bbbbbb

EOF

 

而如果我们一行一行的敲入如上命令,比如先键入cat << EOF 然后回车,会进入一个输入提示符,这时候再输入的信息,也会当做标准输入,被重定向到cat中,当然,要以EOF标准输入的结束。

 

 

当然,我们也可以结合标准输出重定向将输出的内容再次重定向到别的文件中

cat << EOF > f1

aaaaaa

bbbbbb

EOF

也可以这样写

cat > f1 << EOF

aaaaaa

bbbbbb

EOF

 

 

 

 

以下两种写法都可在脚本中执行oraclesql语句,并将执行后的标准输重定向到指定的日志文件。

以下两种写法表示将sqlcmd1sqlcmd2当做标准输入重定向到sqlplus的标准输入,相当于不用手动在sqlplus提示符中输入sql语句,而是写好了一次性当做标准输入重定向过去,然后再将命令执行结果使用标准输出重定向,重定向到指定的日志文件中。

sqlplus >> /tmp/out.log << EOF

sqlcmd1

sqlcmd2

EOF

或者

sqlplus << EOF >> /tmp/out.log

sqlcmd1

sqlcmd2

EOF

 

 

如果某个敲击某个命令以后,会进入自己的命令行模式,如fdisk这种命令,但是我们需要脚本去完成我们的命令

那么还有一种实现方式,这种写法用到了管道。

echo '命令1

命令2

行首回车表示直接回车

命令4' | fdisk /dev/sdd9




管道

管道符代表将一个命令的STDOUT作为另一个命令的STDIN

管道符可以多次传递

注意,管道是将一个命令的标准输出(不包含标准错误)作为另一个命令的标准输入

如果想将标准输出和标准错误同时作为另一个命令的标准输入,可以使用如下两种方法的任意一种

CMD1 2>&1 | CMD2

CMD1 |& CMD2

 



tee命令

tee命令会将自己接收到的 标准输入信息 当做 标准输出  输出到屏幕同时输出到指定的文件

 

但是,请注意,按照如下写法一,如果cmd1执行时出错,则不会有错误信息传递给tee命令,原因是因为管道默认只会传递标准输出,而不传递标准错误,所以 ,如果考虑到cmd1执行出错的情况下,保证不管是标准输出和标准错误都能不遗漏的输出到屏幕和文件,请使用写法二,其实写法二是利用了管道同时传递标准输出和标准错误的技巧。

 

写法一:cmd1 | tee outfile

写法二:cmd1 2>&1 | tee outfile 或者 cmd1 |& tee outfile


欢迎访问博主的个人博客

http://www.zsythink.net/