Linux重定向




程序:指令+数据

读入数据: Input

输出数据: Output

打开的文件都有一个fd: file descriptor (文件描述符)

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

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

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

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


[root@localhost /testdir]# ll /dev/std*

lrwxrwxrwx. 1 root root 15 Aug 28 22:22 /dev/stderr -> /proc/self/fd/2

lrwxrwxrwx. 1 root root 15 Aug 28 22:22 /dev/stdin -> /proc/self/fd/0

lrwxrwxrwx. 1 root root 15 Aug 28 22:22 /dev/stdout -> /proc/self/fd/1


I/O重定向:改变默认位置

 

STDOUT和STDERR可以被重定向到文件:

命令 操作符号 文件名

支持的操作符号包括:

>      STDOUT重定向到文件

2>     STDERR重定向到文件

&>     把所有输出重定向到文件

> 文件内容会被覆盖

# set -C: 禁止将内容覆盖已有文件,但可追加

强制覆盖: >|

# set +C: 允许覆盖

>> 原有内容基础上,追加内容

   2>: 覆盖重定向错误输出数据流;

   2>>: 追加重定向错误输出数据流;

   标准输出和错误输出各自定向至不同位置:

COMMAND > /path/to/file.out 2> /path/to/error.out

      合并标准输出和错误输出为同一个数据流进行重定向:

&>:覆盖重定向

&>>:追加重定向

COMMAND > /path/to/file.out 2> &1 (顺序很重要)

COMMAND >> /path/to/file.out 2>> &1

find /etc -name passwd 2> /dev/null

      ():合并多个程序的STDOUT

[root@localhost /testdir]# (cal 2016;cal 2017) > cal.txt    #将两个命令的结果输出到cal.txt文件中

 

[root@localhost /testdir]# (date; lsdf) &> all.txt          #将标准输出和错误输出全部写入到all.txt文件中

[root@localhost /testdir]# cat all.txt

Mon Aug 29 20:04:27 CST 2016

bash: lsdf: command not found...

 

注意:

1、shell遇到”>”操作符,会判断右边文件是否存在,如果存在就先删除,并且创建新文件。不存在直接创建。 无论左边命令执行是否成功。右边文件都会变为空。

2、“>>”操作符,判断右边文件,如果不存在,先创建。以添加方式打开文件,会分配一个文件描述符[不特别指定,默认为1,2]然后,与左边的标准输出(1)或错误输出(2) 绑定。

3、当命令执行完,绑定文件的描述符也自动失效。0,1,2又会空闲。

4、一条命令启动,命令的输入,正确输出,错误输出,默认分别绑定0,1,2文件描述符。

5、一条命令在执行前,先会检查输出是否正确,如果输出设备错误,将不会进行命令执行

 

示例:

 

[root@localhost /testdir]# set -C bs                    #禁止将内容覆盖已有文件

[root@localhost /testdir]# echo "nnnnnnnnnn" > bs

-bash: bs: cannot overwrite existing file

[root@localhost /testdir]# echo "mmmmmmmmm" >| bs

[root@localhost /testdir]# echo "nnnnnnnn" >> bs

[root@localhost /testdir]# cat bs

mmmmmmmmm

nnnnnnnn

[root@localhost /testdir]# set +C bs                    #允许覆盖

[root@localhost /testdir]# echo "aaaaaaaa" > bs

 

[root@localhost /testdir]# echo "Hello World" > wel    #覆盖写入

[root@localhost /testdir]# echo "Hello" >> wel         #追加写入

[root@localhost /testdir]# cat wel

Hello World

Hello

 

[root@localhost /testdir]# cat < /etc/issue           #从指定文件读取内容


\S

Kernel \r on an \m


[root@localhost /testdir]# lsdfdf &> err.txt        #不管是标准输出还是错误输出都写入到err.txt文件中

[root@localhost /testdir]# cat err.txt

              bash: lsdfdf: command not found...




从文件中导入STDIN



使用 来重定向标准输入


某些命令能够接受从文件中导入的STDIN:

 

    /etc/issue中的小写字符都转换成写写字符

    [root@localhost /testdir]# tr 'a-z' 'A-Z' < /etc/issue

    \S

    KERNEL \R ON AN \M

     

    删除issue文件中的指定的字符

    [root@localhost /testdir]# tr -d 'a-h' < /etc/issue

    \S

    Krnl \r on n \m

     

    [root@localhost /testdir]# cat > t < test

    [root@localhost /testdir]# cat t

    1212121

    [root@localhost /testdir]# cat test

    1212121

 

 

把多行发送给STDIN



使用“ <<终止词”命令从键盘把多行重导向给STDIN

直到 终止词 位置的所有文本都发送给STDIN

有时被称为就地文本( heretext)

 

[root@localhost /testdir]# cat > file <<end

> hello

> world

> hi,

> end

[root@localhost /testdir]# cat file

hello

world

hi,


  管道



    管道(使用符号“ |”表示)用来连接命令

命令1 | 命令2 | 命令3 |

    将命令1STDOUT发送给命令2STDIN,命令2STDOUT发送到命令3STDIN

        STDERR默认不能通过管道转发,可利用2>&1 |& 实现

    最后一个命令会在当前shell进程的子shell进程中执行用来


    组合多种工具的功能


[root@localhost /testdir]# ls

all.txt  cal.txt  err.txt  file

[root@localhost /testdir]# ls | tr 'a-z' 'A-Z'

ALL.TXT

CAL.TXT

ERR.TXT

FILE

    less :一页一页地查看输入:

[root@localhost /testdir]# ls -l /etc/ | less#分页显示/etc目录下的列表

    mail: 通过电子邮件发送输入:

[root@localhost /testdir]# echo "test mail" | mail -s test root#root发送邮件

    lpr:把输入发送给打印机

[root@localhost /testdir]# echo "test print" | lpr -P printer

 

     重定向到多个目标( tee

    命令1 | tee 文件名 | 命令2

        把命令1STDOUT保存在文件名中,然后管道输入给命令2

     使用:

    保存不同阶段的输出

    复杂管道的故障排除

    同时查看和记录输出

 

[root@localhost /testdir]# ls | tee sc.txt | tr 'a-z' 'A-Z'

ALL.TXT

CAL.TXT

ERR.TXT

FILE

[root@localhost /testdir]# cat sc.txt

all.txt

cal.txt

err.txt

file