bash的I/O重定向及管道 

    程序是由程序+指令组成;或者是数据结构+算法

    程序数据来自哪里,处理的结果又存放于哪里?

    程序必须能够读入输出然后经过加工来产生结果;程序获取的数据可以使数据也可以hi变量、数据、列表文件等等,程序生产出来的结果可以是变量、数据、列表、文件等。也就是说,程序都有读入数据和输入数据的需求。

    读入数据:Input

    输出数据:Output

        通常对于程序来说,输入输出数据可以是键盘、鼠标、显示器等;当然有时候输入的数据是程序自身内部所具有的,但我们认为这些数据应该是通过外部输入的,同样,输出的数据也有显示器或文件,因此我们多了一个选择,到底是从哪里输入数据,产生的数据又存放在那里。因此就应该有一种缺省的定义,指认默认的输入输出途径,当程序不指从哪里输入,输出到那儿,默认的途径就是进行数据交换。

   一般缺省的输入我们称之为:标准输入,缺省的输出称之为:标准输出。

    标准输入:键盘

    标准输出:显示器

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

linux给程序提供三I/O设备

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

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

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

I/O重定向:改变标准位置

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

     命令    操作符号    文件名

     ls   /etc/    >   /tmp/1.out

   支持的操作符号包括以下几种:

    >    把STDOUT重定向到文件

    2>  把STDERR重定向到文件

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


wKioL1ebQcezSKJsAAAxkncmers186.png-wh_50

        当我查看/etc/issue文件时,不将文件的内容输出到屏幕而是将文件内容重定向到/tmp/1.out文件当中,当我列出/root目录下面不存在的文件时,本应该会提示文件不存在的信息,利用“2>”将报错信息重定向到/tmp/2.out,&符号是将正确的信息和错误的信息一起重定向到某个文件。

当我想再次使用>时,第一次重定向的文件将会被覆盖,使用“>>”追加符号,会将正确的输出追加到文件里,这是我们可以使用set -C禁止将内容覆盖已有文件,但可追加强制覆盖:>|,如果想再次开启覆盖重定向只需要set  + C即可。

>>在原有内容的基础之上,追加新内容

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

标准输出和错误输出各自定向到不同的位置

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

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

&>:覆盖重定向,将正确和错误信息一同覆盖输入到同一个文件

&>>:追加重定向,将正确和错误信息一同追加到原有内容的后面

command >/path/to/file.out 2>&1执行某条命令后将错误的信息当成正确的信息重定向到文件

command >> /path/to/fileout 2>>&1跟上面类似,只不过是追加输出内容到文件

():合并多个程序的STDOUT

      (ls /etc/issue;cat /etc/passwd )> all.out



tr命令   

tr [OPTION]... SET1 [SET2]
-c或--complerment:取字符集的补集

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

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

-t或--truncate-set1:将第一个字符集对应字符转化为字符集对应的字符


wKiom1ebSQbx7hgmAAATMEpo5KE846.jpg-wh_50

wKioL1ebSQbyhOtOAAAPIYHvR74123.jpg-wh_50


从文件中导入STDIN

使用<来重定向到标准输入

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

    tr  'a-z'  'A-Z' < /etc/issue

wKiom1ebSZLB7EjKAAAXjuLIq5E538.jpg-wh_50

这个命令是将/etc/issue文件里面的内容里的小写字符全部替换成大写字符

tr -d  abcd </etc/fstab  删除fstab文件的所有abc中任意字符

wKioL1ebSmuCgg0OAAAgcxlDpeI822.jpg-wh_50

        <<EOF标准输入,EOF是起始符(这个EOF是而已随意起名的,但是必须得保证结束符号也用相同的字符),按回车之后等待键盘输入内容,输入完内容之后同样 以EOF结尾哦结束符来结束交互并且将标准入的内容又重定向到文件中去

    举个例子发个邮件给hadoop

mail  -s  “good”  hadoop  <<END

>how  are you  ?

>my name is `id -nu`

>my hostname is `hostname`

>END



管道  

    前一个命令的输出作为后一个命令的输入

  command1|command2|command3

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

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

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

组合多种工具的功能

    ls |tr  'a-z '  'A-Z'

wKioL1ebTMfBvTklAAAzBe7MM7E573.jpg-wh_50

管道的应用

less:一页一页的查看输入

  ls  -l   /etc/|less


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

echo  " test site "  |mail -s "test"   hadoop@example.com


重定向到多个目标(tee)

  command1 |tree   filename  |command2

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

wKiom1ebTiiQxppTAAAj-_HJRLU922.jpg-wh_50

使用:

保存不同阶段的输出

复杂管道的故障排除

同时查看和记录输出



练习题 

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

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

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

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

3、一个linux用户给root发邮件,要求邮件标题为”help”,邮件正文如下:
Hello, I am 用户名,the system version is here,please help me to
check it ,thanks!
操作系统版本信息

    mail -s "help"  root  <<EOF

>Hello, I am `id -nu`  ,the system version is here,please help me to
>check it ,thanks!

>`cat /etc/centos-release`

>EOF


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

    ls   /root/  |tr  '\n'  '   '

5、file1文件的内容为:”1 2 3 4 5 6 7 8 9 10” 计算出所有数字的总和

    cat 1.file  |xargs  -n1 |echo $[ $(tr '[[:space:]]'+' ) 0 ]

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

     cat /root/1.txt|tr -d '\r'  '   '  

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

    tr  -d -c   ‘[[[:space:]][[:digit:]]'  <“xt.,l 1 jr#!$mn 2 c*/fe 3 uz 4"

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

    echo $PATH|tr ':'  '\n'

9、删除指定文件的空行

        tr  -s  '\n'  << inittab

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

          tr -cs   [[:alpha:]]   '\n' << /etc/inittab