IO重定向与小实验
标准输入和输出
IO重定向
tr、tee命令与管道
首先说一下什么是I/O重定向,所谓I/O重定向简单来说就是一个过程,这个过程捕捉一个文件,或者命令,程序,脚本的输出,然后把捕捉到的输出,作为输入发送给另外一个文件,命令,程序,或者脚本。
如果谈到I/O重定向,就涉及到文件标识符,在Linux系统中,系统为每一个打开的文件指定一个文件标识符以便系统对文件进行跟踪,文件标识符是一个数字,不同数字代表不同的含义,默认情况下,系统占用了3个,分别是0标准输入(stdin),1标准输出(stdout),2标准错误(stderr)。
标准输入通常指键盘的输入
标准输出通常指显示器的输出
标准错误通常也是定向到显示器
输出重定向与错误输出重定向:
stdout和stderr可以被重定向到文件:命令 操作符号 文件名 支持的操作符号包括:
> 把stdout重定向到文件
[root@localhost ~]# ls > f1 [root@localhost ~]# cat f1 anaconda-ks.cfg Desktop Documents Downloads f1 install.log install.log.syslog Music 这里把ls命令输出的结果定向到文件f1, 把原本要显示到显示器上的结果输出给f1。 然后查看f1文件的结果就是ls命令的结果
2> 把stderr重定向到文件
[root@localhost ~]# ls /ttt ls: cannot access /ttt: No such file or directory [root@localhost ~]# ls /ttt 2> f1 [root@localhost ~]# cat f1 ls: cannot access /ttt: No such file or directory 这里我们先用ls命令输出一个错误结果 把ls /ttt的结果使用错误重定向到文件f1 查看f1文件里的结果
&> 把所有输出重定向到文件
[root@localhost ~]# ls /root /ttt &> f1 [root@localhost ~]# cat f1 ls: cannot access /ttt: No such file or directory /root: anaconda-ks.cfg Desktop Documents Downloads f1 install.log install.log.syslog Music Pictures Public Templates Videos 使用&>可以把正确和错误的输出都定向到文件f1中。
标准输出和错误输出各自定向至不同位置:
COMMAND > /path/to/file.out 2> /path/to/error.out
请看下面的示例:
[root@localhost ~]# ls /ttt /root > f1.out 2> f2.out [root@localhost ~]# cat f1.out /root: anaconda-ks.cfg Desktop Documents Downloads f1.out f2.out install.log install.log.syslog Music Pictures Public Templates Videos [root@localhost ~]# cat f2 cat: f2: No such file or directory 这里我们发现ls /root 是正确输出,在文件f1.out里面 ls /ttt为错误输出,在文件f2.out里面
注意: 这里的> 到文件会把文件内容覆盖
使用 set -C 禁止将内容覆盖到已有的文件,但是可以追加到文件
使用 set +C 允许覆盖
强制覆盖:>|
>> 原有内容基础上,追加内容
2> 覆盖重定向错误输出数据流;
2>> 追加重定向错误输出数据流;
合并标准输出和错误输出为同一个数据流进行重定向:
&>:覆盖重定向
&>>:追加重定向
():合并多个程序的stdout
[root@localhost ~]# (ls /root; cat /etc/issue) > f1 [root@localhost ~]# cat f1 anaconda-ks.cfg Desktop Documents Downloads f1 f1.out f2.out install.log install.log.syslog Music Pictures Public Templates Videos CentOS release 6.8 (Final) Kernel \r on an \m Mage Education Learning Services http://www.magedu.com
管道:
命令1 | 命令2 | 命令3 | …
管道是Linux中很重要的一种通信方式,是把一个程序的输出直接连接到另一个程序的输入。管道命令操作符是:”|”,它仅能处理经由前面一个指令传出的正确输出信息,也就是 standard output 的信息,对于 stdandard error 信息没有直接处理能力。然后,传递给下一个命令,作为标准的输入 standard input.
command1正确输出,作为command2的输入 然后comand2的输出作为,comand3的输入 ,comand3输出就会直接显示在屏幕上面了。
tr命令:
tr用来从标准输入中通过替换或删除操作进行字符转换。
用法:
tr [OPTION]... SET1 [SET2]
常用的选项:
选项:
-c或——complerment:取字符集的补集
-d或——delete:删除所有属于第一字符集的字符;
这里我们把-c 与 -d 选项一起使用来举个例子:
[root@localhost ~]# echo 12bchsa333nd | tr -cd '[0-9]' 12333[root@localhost ~]# 我们使用echo 输出一串字符通过管道送给tr ,使用 -c(补集) -d(删除) 也就是删除除了[0-9]之外的其他字符
-s或—squeeze-repeats:把连续重复的字符以单独一个字符表示
[root@localhost ~]# cat f1 aaaaaaa bbbbbbb ccccccc [root@localhost ~]# cat f1 | tr -s "abc" a b c
-t或--truncate-set1:先删除第一字符集较第二字符集多出 的字符
[root@localhost ~]# echo abcde | tr 'a-d' 'xyz' xyzze 后面替换的不够用最后的字符替换 [root@localhost ~]# echo abcde | tr -t 'a-d' 'xyz' xyzde 后面替换的字符不够不进行替换
tee命令:
命令1 | tee 文件名 | 命令2
把命令1的STDOUT保存在文件名中,然后管道输入给命令2
使用:
保存不同阶段的输出
复杂管道的故障排除
同时查看和记录输出
[root@localhost ~]# ls /root | tee f1 | cat >> f1 [root@localhost ~]# cat f1 anaconda-ks.cfg Desktop Documents Downloads f1 f1.out f2.out f3 install.log install.log.syslog Music Pictures Public Templates Videos anaconda-ks.cfg Desktop Documents Downloads f1 f1.out f2.out f3 install.log install.log.syslog Music Pictures Public Templates Videos
输入重定向:
从文件中导入stdin
使用<来重定向标准输入
使用<来重定向标准输入
某些命令能够接受从文件中导入的stdin:
tr ‘a-z’ ‘A-Z’< /etc/issue
[root@localhost ~]# tr 'a-z' 'A-Z' < /etc/issue CENTOS RELEASE 6.8 (FINAL) KERNEL \R ON AN \M MAGE EDUCATION LEARNING SERVICES HTTP://WWW.MAGEDU.COM 命令会把/etc/issue中的小写字符都转换成大写字符
tr –d abc < /etc/fstab
[root@localhost ~]# tr -d 'a-z' < /etc/fstab # # // # C M J 25 09:40:54 2016 # # A , , '//' # S (5), (8), (8) / (8) # ///0- / 4 1 1 UUID=95470-1451-408-9902-4032569 / 4 1 2 ///0- / 4 1 2 ///0- / 4 1 2 ///0- 0 0 // 0 0 // =5,=620 0 0
#cat > filea < fileb
[root@localhost ~]# cat > f1 sdasdasd asd asd asd asd [root@localhost ~]# touch f3 [root@localhost ~]# cat > f3 <f1 [root@localhost ~]# cat f1 sdasdasd asd asd asd asd [root@localhost ~]# cat f3 sdasdasd asd asd asd asd 按ctrl+d离开,可以使用文件来代替键盘的输入 cat > f1 使用cat 输入字符到f1文件 cat > f3 <f1 使用cat命令从f1文件获取输入内容,输出到f3文件。
多行重定向 <<eof
使用“<<终止词”命令从键盘把多行重导向给stdin
邮件使用多行重定向
[zang@localhost ~]$ mail -s test root <<eof > hello, > this is test > hahaha... > eof [root@localhost ~]# mail Heirloom Mail version 12.5 7/5/10. Type ? for help. "/var/spool/mail/root": 2 messages 2 new >N 1 user@localhost.local Mon Jul 25 11:03 1010/46619 "[abrt] full crash report" N 2 zang@localhost.local Mon Jul 25 11:34 20/617 "test" & 2 Message 2: From zang@localhost.localdomain Mon Jul 25 11:34:47 2016 Return-Path: <zang@localhost.localdomain> X-Original-To: root Delivered-To: root@localhost.localdomain Date: Mon, 25 Jul 2016 11:34:46 +0800 To: root@localhost.localdomain Subject: test User-Agent: Heirloom mailx 12.5 7/5/10 Content-Type: text/plain; charset=us-ascii From: zang@localhost.localdomain Status: R hello, this is test hahaha... &
管道与重定向区别是:
1、左边的命令应该有标准输出 | 右边的命令应该接受标准输入
左边的命令应该有标准输出 > 右边只能是文件
左边的命令应该需要标准输入 < 右边只能是文件
2、管道触发两个子进程执行"|"两边的程序;而重定向是在一个进程内执行
小实验
1、将/etc/issue文件中的内容转换为大写后保存至/tmp/issue.out文件中
[root@localhost ~]# cat /etc/issue | tr [a-z] [A-Z] \S KERNEL \R ON AN \M
2、将当前系统登录用户的信息转换为大写后保存至/tmp/who.out文件中
[root@localhost ~]# who | tr [a-z] [A-Z] > /tmp/who.out [root@localhost ~]# cat /tmp/who.out ROOT PTS/0 2016-07-25 11:04 (:0) ROOT TTY2 2016-07-25 11:03 ROOT :0 2016-07-25 11:04 (:0) ROOT PTS/2 2016-07-25 11:06 (10.1.250.72) ROOT PTS/3 2016-07-25 11:32 (10.1.250.72)
3、一个linux用户给root发邮件,要求邮件标题为”help”,邮件正文如下:
Hello, I am 用户名,the system version is here,pleasehelp me to check it ,thanks!
操作系统版本信息
[zang@localhost ~]$echo -e "Hello,I am `whoami`,the version is here ,pleasehelp me to chick it ,thanks! /n`lsb_release`" | mail -s "help" root
4、将/root/下文件列表,显示成一行,并文件名之间用空格隔开
[root@localhost ~]# echo $(ls -a) > f1 [root@localhost ~]# cat f1 . .. anaconda-ks.cfg .bash_history .bash_logout .bash_profile .bashrc .cache .config .cshrc Desktop Documents Downloads .esd_auth f1 .gstreamer-0.10 .gtkrc-2.0-kde4 .kde .local Music Pictures Public .ssh .tcshrc Templates Videos .Xauthority [root@localhost ~]# ls -a | tr '\n' ' ' . .. anaconda-ks.cfg .bash_history .bash_logout .bash_profile .bashrc .cache .config .cshrc Desktop Documents Downloads .esd_auth f1 .gstreamer-0.10 .gtkrc-2.0-kde4 .kde .local Music Pictures Public .ssh .tcshrc Templates Videos .Xauthority
5、file1文件的内容为:”1 2 3 4 5 6 7 8 9 10” 计算出所有数字的总和
[root@localhost ~]# echo $[1+2+3+4+5+6+7+8+9+10] 55 [root@localhost ~]# echo "1 2 3 4 5 6 7 8 9 10" | tr ' ' '+' |bc 55 [root@localhost ~]# echo $[`echo "1 2 3 4 5 6 7 8 9 10" | tr ' ' '+'`] 55
6、删除Windows文本文件中的'^M'字符
[root@localhost ~]# ls anaconda-ks.cfg Desktop Documents Downloads f1 Music Pictures Public Templates Videos zzzzz.txt [root@localhost ~]# cat zzzzz.txt -A inode^M$ reference^M$ contents^M$ directory^M$ ^M$ list directory entries instead of contents, and do not dereference symbolic links^M$ [root@localhost ~]# cat zzzzz.txt | tr -d '\r' >f1 [root@localhost ~]# cat f1 -A inode$ reference$ contents$ directory$ $ list directory entries instead of contents, and do not dereference symbolic links$
7、处理字符串“xt.,l 1 jr#!$mn2 c*/fe3 uz4”,只保留其中的数字和空格
[root@localhost ~]# echo 'xt.,l 1 jr#!$mn2 c*/fe3 uz4' | tr -cd '[:digit:] [:space:]' 1 2 3 4
8、将PATH变量每个目录显示在独立的一行
[root@localhost ~]# echo $PATH /usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin [root@localhost ~]# echo $PATH | tr ':' '\n' /usr/lib64/qt-3.3/bin /usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /root/bin
9、删除指定文件的空行
[root@localhost ~]# cat f1 -A inode$ $ $ reference$ $ contents$ $ $ directory$ $ list directory entries instead of contents, and do not dereference symbolic links$ [root@localhost ~]# cat f1 | tr -s '\n' inode reference contents directory list directory entries instead of contents, and do not dereference symbolic links
10、将文件中每个单词(字母)显示在独立的一行,并无空行
[root@localhost ~]# cat /etc/init.d/functions | tr -cs '[:alpha:]' '\n'
---