Linux重定向
程序:指令+数据 读入数据: Input 输出数据: Output 打开的文件都有一个fd: file descriptor (文件描述符) Linux给程序提供三种I/O设备 标准输入( STDIN) 0 默认接受来自键盘的输入 标准输出( STDOUT) 1 默认输出到终端窗口 标准错误( STDERR) 2 默认输出到终端窗口
[iyunv@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 [iyunv@localhost /testdir]# (cal 2016;cal 2017) > cal.txt #将两个命令的结果输出到cal.txt文件中
[iyunv@localhost /testdir]# (date; lsdf) &> all.txt #将标准输出和错误输出全部写入到all.txt文件中 [iyunv@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、一条命令在执行前,先会检查输出是否正确,如果输出设备错误,将不会进行命令执行
示例:
[iyunv@localhost /testdir]# set -C bs #禁止将内容覆盖已有文件 [iyunv@localhost /testdir]# echo "nnnnnnnnnn" > bs -bash: bs: cannot overwrite existing file [iyunv@localhost /testdir]# echo "mmmmmmmmm" >| bs [iyunv@localhost /testdir]# echo "nnnnnnnn" >> bs [iyunv@localhost /testdir]# cat bs mmmmmmmmm nnnnnnnn [iyunv@localhost /testdir]# set +C bs #允许覆盖 [iyunv@localhost /testdir]# echo "aaaaaaaa" > bs
[iyunv@localhost /testdir]# echo "Hello World" > wel #覆盖写入 [iyunv@localhost /testdir]# echo "Hello" >> wel #追加写入 [iyunv@localhost /testdir]# cat wel Hello World Hello
[iyunv@localhost /testdir]# cat < /etc/issue #从指定文件读取内容
\S Kernel \r on an \m
[iyunv@localhost /testdir]# lsdfdf &> err.txt #不管是标准输出还是错误输出都写入到err.txt文件中 [iyunv@localhost /testdir]# cat err.txt bash: lsdfdf: command not found...
从文件中导入STDIN
使用 < 来重定向标准输入
某些命令能够接受从文件中导入的STDIN:
把/etc/issue中的小写字符都转换成写写字符 [iyunv@localhost /testdir]# tr 'a-z' 'A-Z' < /etc/issue \S KERNEL \R ON AN \M
删除issue文件中的指定的字符 [iyunv@localhost /testdir]# tr -d 'a-h' < /etc/issue \S Krnl \r on n \m
[iyunv@localhost /testdir]# cat > t < test [iyunv@localhost /testdir]# cat t 1212121 [iyunv@localhost /testdir]# cat test 1212121
把多行发送给STDIN
使用“ <<终止词”命令从键盘把多行重导向给STDIN 直到 终止词 位置的所有文本都发送给STDIN 有时被称为就地文本( heretext)
[iyunv@localhost /testdir]# cat > file <<end > hello > world > hi, > end [iyunv@localhost /testdir]# cat file hello world hi,
管道
管道(使用符号“ |”表示)用来连接命令 命令1 | 命令2 | 命令3 | … 将命令1的STDOUT发送给命令2的STDIN,命令2的STDOUT发送到命令3的STDIN STDERR默认不能通过管道转发,可利用2>&1 或 |& 实现 最后一个命令会在当前shell进程的子shell进程中执行用来
组合多种工具的功能
[iyunv@localhost /testdir]# ls all.txt cal.txt err.txt file [iyunv@localhost /testdir]# ls | tr 'a-z' 'A-Z' ALL.TXT CAL.TXT ERR.TXT FILE less :一页一页地查看输入: [iyunv@localhost /testdir]# ls -l /etc/ | less#分页显示/etc目录下的列表 mail: 通过电子邮件发送输入: [iyunv@localhost /testdir]# echo "test mail" | mail -s test root#给root发送邮件 lpr:把输入发送给打印机 [iyunv@localhost /testdir]# echo "test print" | lpr -P printer
重定向到多个目标( tee) 命令1 | tee 文件名 | 命令2 把命令1的STDOUT保存在文件名中,然后管道输入给命令2 使用: 保存不同阶段的输出 复杂管道的故障排除 同时查看和记录输出
[iyunv@localhost /testdir]# ls | tee sc.txt | tr 'a-z' 'A-Z' ALL.TXT CAL.TXT ERR.TXT FILE [iyunv@localhost /testdir]# cat sc.txt all.txt cal.txt err.txt file
|