标准I/O和管道


标准输入和输出


程序是由指令+数据组成

程序的数据流有三种:


输入数据流:<--标准输入(stdin),一般默认是键盘

输出数据流:-->标准输出(stdout),一般默认到终端窗口

错误输出流:-->标准错误(stderr),一般默认到终端窗口


标准输入:0

标准输出:1

错误输出:2


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


输出重定向:将标准输出(stdout)和标准错误(stderr)重定向到指定位置


格式: 命令   操作符号   文件名


支持的操作符号:

>  :把标准输出(stdout)重定向到文件,会覆盖原文件内容

>> :把标准输出(stdout)重定向到文件,会在原有内容基础上,追加内容

wKioL1efLaHgaGkfAABY2uBPg18105.png


说明:上面是讲ll显示的结果输出重定向到文件file中,使用>时,file文件被覆盖了,使用>>时,原文件file和重定向的内容都显示了,是追加内容


2>  :把标准错误(stderr)重定向到文件,会覆盖原内容

2>>:把标准错误(stderr)重定向到文件,会在原内容基础上,追加内容

wKioL1efL83CVDWmAABesJJ4pRY120.png

说明:将命令执行的错误结果显示在file文件中,使用2>时,覆盖了原文件file输出的,使用2>>时,原文       件内容和标准错误都显示了,是追加内容


&>:把所有的输出重定向到文件,不管对错都输出到指定位置,覆盖输出

&>>:把所有的输出重定向到文件,不管对错都输出到指定位置,追加输出

2>&1


wKiom1efNWXw0BOwAADp-hR1RVA308.png

说明:使用&>或者&>>时,执行ll时,是标准输出,lls是标准错误,但是不管是哪个的输出都重定向到file        文件中,


2>&1和&>,&>>效果一样,2>&1是老版本使用,要在最后使用,才有效果,如上图


  command >/path/toshmefile  2>&1

   command>>/path/to/somefile  2>&1

理解:A和B,将A输出到B上,如果对了,就正常输出到B上,如果错误了,内容还是输出在B上



set -C:禁止将内容覆盖已有的文件,但是可以追加强制覆盖 :>|

set +C:允许覆盖

wKiom1efOBriFNPBAABedYQk_NY605.png


合并多个程序的标准输出

(command ;command)>file

wKiom1efOLDTAOtEAAAV1eA3NlU942.png


说明:将ll和echo sha的标准输出一起重定向到file文件中,下图可知,此法只能用于标准输出,

标准错误不能使用

wKiom1efOVqRryZUAAAyDFPUNtE539.png


tr:转换和删除字符


tr [option] .. SET1 [SET2]==>[]非必选


选项:

-c:取字符的补集==>取代所有不属于第一字符集的字符

-d:删除所有属于第一个字符集的字符

-s:把连续重复的字符以单独一个字符表示

-t:将第一个字符集对应字符转换为第二字符集对应的字符


一些用法:

wKioL1efQa6T59kcAABHr8wLr6A876.png


wKioL1efRJWyt5hqAAA-uwMak3I966.png

wKioL1efRe7j09s7AAAftz_EseI185.png

和上面效果一样,不做特别说明


管道:


管道使用符号|来连接命令

command1 |command2 |command3...

1.将命令1的标准输出发送给命令2,作为命令2的标准输入,命令2的标准输出发给command3,作为command3    的标准输入....

2.标准错误默认不能通过管道转发,但是可以利用2>&1或者|&实现

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

4.可以组合多种工具

例如:

wKioL1efSdbiLicYAABauvlTvwA454.pngwKioL1efSwOywICaAAA5I_Ot7iQ494.png



tee命令:


command1 |tee filename | command2

把command1的标准输出保存在文件中,然后管道输入给command2


特点:1.保存不同阶段的输出

      2. 复杂管道的故障排除

      3.同时查看和记录输出

wKioL1efTZih8rDsAABc2k_EWxc943.png

练习:

1 、将/etc/issue 文件中的内容转换为大写后保存至/tmp/issue.out

使用指令:

cat /etc/issue |tr 'a-z' 'A-Z'>/tmp/issue.out
cat /etc/issue
cat /tmp/issue.out

wKioL1efTnzgWExMAABApcAr09Y032.png

2 、将当前系统登录用户的信息转换为大写后保存至/tmp/who.out

使用指令:

who |tr 'a-z' 'A-Z'>/tmp/who.out 

who

cat /tmp/who.out

wKiom1efTwKyx1SGAAAvYia6tbk300.png

3 、一个linux 用户给root 发邮件,要求邮件标题为”help” ,邮件正文如下:

Hello, I am  用户名,the system version is here,please help me to

check it ,thanks!

操作系统版本信息

指令:

echo -e "hello zhengwen \n `uname -r`"|mail -s "help" root@localhost

wKiom1efUsXzJnNNAAEL_RCO5cI629.png-wh_50


 4 、将/root/ 下文件列表,显示成一行,并文件名之间用 空格 隔开

wKiom1efVBuTTRW1AAA3Q2DYy0U664.png

以上可看出,文件列表中,文件默认是占用一行的

所以要显示成一行就是要删掉换行符"\n"

指令:

ls |tr -d '\n'

wKiom1efVRHRB8LBAAAU23u9mT0866.png

 5 、file1 文件 的 内容为:”1 2 3 4 5 6 7 8 9 10” 

指令1:

echo 1 2 3 4 5 6 7 8 9 10|tr ' ' '+'|bc

wKioL1efVjeQ4ZrLAAAIaMjcq9Q704.png

指令2:

echo $[`echo 1 2 3 4 5 6 7 8 9 10|tr ' ' '+'`]

wKiom1efVvaTLuJhAAAUczX7hLM635.png


 6 、删除Windows 文本文件中的'^M' 字符


wKiom1ef5__Cy5bnAAAemh6vD5c683.png

文件test.txt是在windows上复制过来的,cat命令使用-A可看到文本中的'^M’字符,要删除‘^M’tr命令是不能识别‘^M’的,‘^M’转换为八进制为015,将输出结果追加进hah文件中,结果如下

所以指令为:

cat test.txt|tr -d '\015' >hah
cat -A hah

 7 、处理字符串“xt.,l 1 jr#!$mn 2 c*/fe 3 uz 4 ”,只保留其中的数字和空格

思路:要保留数字和空格,则是要将数字和空格之外的全部删掉

echo “xt.,l 1 jr#!$mn 2 c*/fe 3 uz 4 ”|tr -c -d '0-9 \n'
echo 'xt.,l 1 jr#!$mn 2 c*/fe 3 uz 4 '|tr -c -d '0-9 \n'

wKioL1ef7qjxmaG0AAA7gFryW8Y726.png此题陷阱:command !$:可调用上一个命令的最后一个参数,所以要把上面只当做字符引用,使用强引用'',就可实现


 8 、将PATH变量每个目录显示在独立的一行

PATH变量中的目录默认是用“:”隔开的,要显示独立一行,则需要将“:”替换成换行符“\n”

echo $PATH |tr ':' '\n' 独立一行
echo $PATH |tr ':' ' '  空格隔开

wKioL1ef7zugCrmhAAA6P7v3RFI769.png


 9 、删除指定文件的空行


wKiom1ef8beggWWsAAAdKcsjtYc992.png

10 、将文件中每个单词(字母)显示在独立的一行,并无空行

cat /etc/init.d/functions |tr -cs  '[:alpha:]' '\n'

将所有除字母外的字符替换成换行符,-s选项将重复的的字符以单独一个字符表示

wKiom1ef8-TC_wR7AAAWZTtCaRo326.png