5-1 标准I/O和管道

标准I/O和管道

程序:指令+数据

  • 读入数据:Input
  • 输出数据:Output

打开的文件都有一个fd: file descriptor (文件描述符)
Linux给程序提供三种 I/O 设备

  • 标准输入(STDIN)-0 默认接受来自终端窗口的输入
  • 标准输出(STDOUT)-1 默认输出到终端窗口
  • 标准错误(STDERR)-2 默认输出到终端窗口

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

文件描述符在系统中的位置:

[root@centos8 ~]#ls -l /proc/$$/fd
total 0
lrwx------. 1 root root 64 Oct  5 09:06 0 -> /dev/pts/0
lrwx------. 1 root root 64 Oct  5 09:06 1 -> /dev/pts/0
lrwx------. 1 root root 64 Oct  5 09:06 2 -> /dev/pts/0
lrwx------. 1 root root 64 Oct  5 09:08 255 -> /dev/pts/0
lr-x------. 1 root root 64 Oct  5 09:06 3 -> /var/lib/sss/mc/passwd
lrwx------. 1 root root 64 Oct  5 09:06 4 -> 'socket:[48411]'

这就是系统运行时内存中对应的文件描述符对应的文件,0,1,2都输出向终端,而重定向即可改变标准输入,输出,错误的输出位置。

hostame >a.txt
#不同命令的标准输入输出是由系统或者程序判定的,而不是想当然的认为是输出或者错误,有时候标准错误可能只是一个提示而已

标准输入要求有内容,并且是一次传入的,在命令执行时就已经读取并执行了,之后再传入内容也不会再输入了

输出和错误重新定向到文件

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

  • 命令 操作符号 文件名

支持的操作符号包括:

  • > 把STDOUT重定向到文件
  • 2> 把STDERR重定向到文件
  • &> 把所有输出重定向到文件

> 文件内容会被覆盖

  • set -C 禁止将内容覆盖已有文件,但可追加
  • >| file 强制覆盖
  • 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

():合并多个程序的STDOUT

  • ( cal 2007 ; cal 2008 ) > all.txt

tr命令

tr 转换和删除字符
tr [OPTION]... SET1 [SET2]
选项:

  • -c –C --complement:取字符集的补集
  • -d --delete:删除所有属于第一字符集的字符
  • -s --squeeze-repeats:把连续重复的字符以单独一个字符表示
  • -t --truncate-set1:将第一个字符集对应字符转化为第二字符集对应的字符
SETs are specified as strings of characters.  Most represent themselves.
Interpreted sequences are:

  \NNN            character with octal value NNN (1 to 3 octal digits)
  \\              backslash
  \a              audible BEL
  \b              backspace
  \f              form feed
  \n              new line
  \r              return
  \t              horizontal tab
  \v              vertical tab
  CHAR1-CHAR2     all characters from CHAR1 to CHAR2 in ascending order
  [CHAR*]         in SET2, copies of CHAR until length of SET1
  [CHAR*REPEAT]   REPEAT copies of CHAR, REPEAT octal if starting with 0
  [:alnum:]       all letters and digits
  [:alpha:]       all letters
  [:blank:]       all horizontal whitespace
  [:cntrl:]       all control characters
  [:digit:]       all digits
  [:graph:]       all printable characters, not including space
  [:lower:]       all lower case letters
  [:print:]       all printable characters, including space
  [:punct:]       all punctuation characters
  [:space:]       all horizontal or vertical whitespace
  [:upper:]       all upper case letters
  [:xdigit:]      all hexadecimal digits
  [=CHAR=]        all characters which are equivalent to CHAR

输入重定向和管道

从文件导入STDIN

使用 < 来重定向标准输入
某些命令能够接受从文件中导入的STDIN

  • tr ‘a-z’ ‘A-Z’< /etc/issue
    该命令会把/etc/issue中的小写字符都转换成大写字符

删除fstab文件中的所有abc中任意字符

  • tr –d abc < /etc/fstab

cat > file

  • 123
  • 45678
  • 按ctrl+d离开,可以使用文件来代替键盘的输入

cat < file1 > file2
cat < file1 >> file1

把多行发送给STDIN

使用“<<终止词”命令从键盘把多行重导向给STDIN

  • 直到 终止词 位置的所有文本都发送给STDIN
  • 有时被称为就地文本(here documents)
mail -s "Please Call" root <<END 
> Hi Wang
>
> Please give me a call when you get in. We may need 
> to do some maintenance on server1. 
>
> Details when you're on-site
> Zhang
> END

管道

管道(使用符号“|”表示)用来连接命令:

  • 命令1 | 命令2 | 命令3 | …
    • 将命令1的STDOUT发送给命令2的STDIN,命令2的STDOUT发送到命令3的STDIN
    • STDERR默认不能通过管道转发,可利用2>&1 或 |& 实现
    • 最后一个命令会在当前shell进程的子shell进程中执行
    • 组合多种工具的功能
      • ls | tr ‘a-z’ ‘A-Z’

示例:

  • less :一页一页地查看输入
    • ls -l /etc | less
  • mail: 通过电子邮件发送输入
    • echo "test email" | mail -s "test" root
  • bc:算术运算
    • echo "2^3" |bc

管道中的-符号:

  • 临时的匿名变量
  • 示例: 将 /home 里面的文件打包,但打包的数据不是记录到文件,而是传送到 stdout,经过管道后,将 tar -cvf - /home 传送给后面的 tar -xvf - , 后面的这个 - 则是取
    前一个命令的 stdout,因此,就不需要使用临时file了
    • tar -cvf - /home | tar -xvf -

重定向到多个目标(tee)

命令1 | tee [-a ] 文件名 | 命令2

  • 把命令1的STDOUT保存在文件中,做为命令2的输入
  • -a 追加

使用:

  • 保存不同阶段的输出
  • 复杂管道的故障排除
  • 同时查看和记录输出

文件中字符显示颜色

echo -e '\e[31;1mred\e[0m'

[[31mred[[0m 这是再vim中标识字符颜色
^[这个是一个字符,同时按住Ctrl+v松开摁左方向键就可以打出来了
\e[31m 代表颜色开始
\e[0m 代表颜色结束,其实是无色开始,也就是代表有颜色结束了

tr -d:删除目标内容比如'\n'换行符,再比如' '空格符等
tr ' ' +< bc.log > bc2.log 将bc.log中的空格替换为+然后输出到bc2.log文件中
cat > cat.log时,时单行重定向,写入一行回车时即写入文件
cat > cat.log <<EOF 这时候输入换行也不会写入文件,只有当输入EOF这个结束符时结束输入文件,这个EOF可以替换为其他字符,同时这串字符前面不能有其他字符,空格也不行
<<即为多行重定向
如果向让第一个命令的标准输出作为第二个命令的标准输入就可以使用管道
echo {1..100} |tr ' ' + |bc 将1到100展开,然后传给tr将空格替换为加号,然后传给bc计算

seq -s +100 这样就会输出1+2+..+100的数字

posted @ 2019-10-10 15:35  kjalbert  阅读(183)  评论(0编辑  收藏  举报