标准I/O和管道

jpeg

标准输入和输出

  • Linux给程序提供三种I/O设备
    ♦ 标准输入(STDIN)-0 默认接受来自键盘的输入
    ♦ 标准输出(STDOUT)-1 默认输出到终端窗口
    ♦ 标准错误(STDERR)-2 默认输出到终端窗口

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

  • 标准输出和标准错误可以被重定向到文件
    ♦ 命令 操作符号 文件名

  • 支持的操作符号包括:
    ♦ > 把STDOUT重定向到文件
     ➢ > 文件内容会被覆盖
     ➢ set –C 禁止将内容覆盖已有文件,但可追加
     ➢ set +C
     ➢ >| file 强制覆盖
     ➢ set +C 允许覆盖
     ➢ >> 原有内容基础上,追加内容

    ♦ 2> 把STDERR重定向到文件
     ➢ 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

    ♦ ():合并多个程序的STDOUT
     ➢ ( cal 2007 ; cal 2008 ) > all.txt

tr命令

  • tr 转换和删除字符
  • tr [OPTION]… SET1 [SET2]
  • 常用选项:
    ♦ -c –C –complement:取字符集的补集
    ♦ -d –delete:删除所有属于第一字符集的字符
    ♦ -s –squeeze-repeats:把连续重复的字符以单独一个字符表示
    ♦ -t –truncate-set1:将第一个字符集对应字符转化为第二字符集对应的字符
     ➢ tr -dc abc | ctrl +d
     ➢ ls /boot /error |& tr 'a-z' 'A-Z'
     ➢ ls /boot /error 2>&1 | tr ‘a-z’ ‘A-Z’
     ➢ seq -s + 100 | bc
     ➢ echo {1..100} | tr “ “ “+” | bc

从文件中导入STDIN

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

  • 某些命令能够接受从文件中导入的STDIN
    ♦ tr ‘a-z’ ‘A-Z’< /etc/issue
    ♦ 该命令会把/etc/issue中的小写字符都转换成写写字符
    ♦ tr –d abc < /etc/fstab 删除fstab文件中的所有abc中任意字符

  • cat > file

    cat > file
    hello world
    #按ctrl+d离开,可以使用文件来代替键盘的输入

    ♦ Cat > filea < fileb

♥ 把多行发送给STDIN

  • 使用“<<终止词”命令从键盘把多行重导向给STDIN
    ♦ 直到 终止词 位置的所有文本都发送给STDIN
    ♦ 有时被称为就地文本(heretext)

管道

  • 管道(使用符号\“|”表示)用来连接命令
  • 命令1 | 命令2 | 命令3 | …
    ♦ 将命令1的STDOUT发送给命令2的STDIN,命令2的STDOUT发送到命令3的STDIN
    ♦ STDERR默认不能通过管道转发,可利用2>&1 或 |& 实现
    ♦ 最后一个命令会在当前shell进程的子shell进程中执行用来
    ♦ 组合多种工具的功能
     ➢ ls | tr ‘a-z’ ‘A-Z’
     ➢ ls -l /etc | less
     ➢ echo “test email” | mail -s “test” user@example.com
     ➢ echo “test print” | lpr -P printer_name

tee

  • 重定向到多个目标
  • 命令1 | tee [-a ] 文件名 | 命令2
    ♦ 把命令1的STDOUT保存在文件中,做为命令2的输入
    -a 追加
  • 使用:
    ♦ 保存不同阶段的输出
    ♦ 复杂管道的故障排除
    ♦ 同时查看和记录输出
     ➢ ls /boot | tee ls.log | tr ‘a-z’ ‘A-Z’

练习

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

    cat /etc/issue | tr [a-z] [A-Z] >> /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 <<EFO
    > Hello ,I am `whoami`,The system version is here,please help me to check it ,thanks!
    > `cat /etc/centos-release`
    > EFO
  4. 将/root/下文件列表,显示成一行,并文件名之间用空格隔开

    ls /root | tr "\n" " "
  5. 计算1+2+3+..+99+100的总和

    echo {1..100} | tr " " "+" | bc 
    seq -s "+" 1 100 | bc
  6. 删除Windows文本文件中的‘^M’字符

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

    echo 'xt.,l 1 jr#clearmn 2 c*/fe 3 uz 4' | tr -dc "[0-9 ]"
  8. 将PATH变量每个目录显示在独立的一行

    echo $PATH | tr ":" "\n"
  9. 将指定文件中0-9分别替代成a-j

    tr [0-9] [a-j] < file
  10. 将文件/etc/centos-release中每个单词(由字母组成)显示在独立一行,并无空行

    cat /etc/centos-release | tr -sc "[:alnum:]." "\n"
  11. 下面那一个选项结果不一样 ( B )
    A app.sh > f1.log 2>&1
    B app.sh 2>&1 > f1.log
    C app.sh 2>f1.log 1>&2
    D app.sh &>f1.log