本章概要
- 三种I/O设备
- 把I/O重定向至文件
- 使用管道
1、三种I/O设备
标准输入和输出
- 程序:指令+数据
读入数据:Input
输出数据:Output - 打开的文件都有一个fd: file descriptor (文件描述符)
查看文件描述符:
(1)在一个窗口随便打开一个文件或程序
[root@centos7 ~]#vim /etc/fstab
(2)在另外一个窗口查看该进程的进程号[root@centos7 ~]#ps aux root 3126 1.5 0.3 151984 5604 pts/1 S+ 10:39 0:00 vim /etc/fstab
(3)查看文件描述符
[root@centos7 ~]#ll /proc/3126/fd total 0 lrwx------. 1 root root 64 Aug 21 10:40 0 -> /dev/pts/1 lrwx------. 1 root root 64 Aug 21 10:40 1 -> /dev/pts/1 lrwx------. 1 root root 64 Aug 21 10:40 2 -> /dev/pts/1 lrwx------. 1 root root 64 Aug 21 10:40 4 -> /etc/.fstab.swp
- linux给程序提供三种I/O设备
标准输入(STDIN)-0 默认接受来自键盘的输入
标准输出(STDOUT)-1 默认输出到终端窗口
标准错误(STDERR)-2 默认输出到终端窗口
I/O重定向:改变默认位置
2、把IO重定向至文件
把输出和错误重定向到文件
- STDOUT和STDERR可以被重定向到文件
命令 操作符号 文件名
支持的操作符号包括:
\> 把STDOUT重定向到文件[root@centos7 ~]#ls > /data/ls.log [root@centos7 ~]#cat /data/ls.log 1GB.file anaconda-ks.cfg bin Desktop Documents Downloads f1 f2 initial-setup-ks.cfg Music Pictures Public Templates Videos
2>把STDERR重定向到文件
[root@centos7 ~]#ls /errot 2> /data/ls2.log [root@centos7 ~]#cat /data/ls2.log ls: cannot access /errot: No such file or directory
&> 把所有输出重定向到文件
[root@centos7 ~]#ls /boot /error &>/data/ls3.log [root@centos7 ~]#cat /data/ls3.log ls: cannot access /error: No such file or directory /boot: config-3.10.0-862.el7.x86_64 efi grub grub2 initramfs-0-rescue-7eab25876df747da952cee5f5a6dbc5f.img initramfs-3.10.0-862.el7.x86_64.img symvers-3.10.0-862.el7.x86_64.gz System.map-3.10.0-862.el7.x86_64 vmlinuz-0-rescue-7eab25876df747da952cee5f5a6dbc5f vmlinuz-3.10.0-862.el7.x86_64
- \> 文件内容会被覆盖
set –C 禁止将内容覆盖已有文件,但可追加
>| file 强制覆盖
set +C 允许覆盖 - >> 原有内容基础上,追加内容
[root@centos7 ~]#cat f1 12345678 [root@centos7 ~]#echo abcde >>f1 [root@centos7 ~]#cat f1 12345678 abcde
- 2> 覆盖重定向错误输出数据流
- 2>> 追加重定向错误输出数据流
- 标准输出和错误输出各自定向至不同位置
COMMAND > /path/to/file.out 2> /path/to/error.out[root@centos7 ~]#ls /boot /error > /data/f1.out 2>/data/f2.out [root@centos7 ~]#cat /data/f1.out /data/f2.out /boot: config-3.10.0-862.el7.x86_64 efi grub grub2 initramfs-0-rescue-7eab25876df747da952cee5f5a6dbc5f.img initramfs-3.10.0-862.el7.x86_64.img symvers-3.10.0-862.el7.x86_64.gz System.map-3.10.0-862.el7.x86_64 vmlinuz-0-rescue-7eab25876df747da952cee5f5a6dbc5f vmlinuz-3.10.0-862.el7.x86_64 ls: cannot access /error: No such file or directory
- 合并标准输出和错误输出为同一个数据流进行重定向
&> 覆盖重定向
&>> 追加重定向
COMMAND > /path/to/file.out 2>&1 (顺序很重要)
多种写法:ls /boot /error > f1.log 2>&1
或ls /boot /error 2> f1.log 1>&2
或( ls /boot /error 2 >&1 ) > f1.log
或ls /boot /error &>f1.log
COMMAND >> /path/to/file.out 2>&1
():合并多个程序的STDOUT
( cal 2007 ; cal 2008 ) > all.txt
tr命令
-
tr 转换和删除字符
-
命令用法:tr [OPTION]... SET1 [SET2]
[root@centos7 ~]#tr 'a-z' 'A-Z' aaabbbcccc AAABBBCCCC eeefff EEEFFF
tr 'abc' '1234' 前三个字符替换,第四个字符4不替换
tr 'abcd' '123' 前三个字符替换,第四个为空,用3代替第四个字符进行替换[root@centos7 data]#tr 'abc' '1234' abcdef 输入内容 123def 显示结果 [root@centos7 data]#tr 'abcd' '123' abcde 输入内容 1233e 显示结果
-
选项:
-c –C --complement:取字符集的补集,即取反
-d --delete:删除所有属于第一字符集的字符[root@centos7 data]#tr -d 'abc' 输入abcdef,结果显示为def abcdef def
-s --squeeze-repeats:把连续重复的字符以单独一个字符表示
[root@centos7 data]#tr -s ' ' ':' aa bb cc dd 输入内容 aa:bb:cc:dd 显示结果
-t --truncate-set1:将第一个字符集对应字符转化为第二字符集对应的字符
特殊字符表示[root@centos7 data]#tr -t 'abcde' '123' abcdef 输入内容 123def 显示结果
tr -dc '[:alpha:]' 删除字母以外的所有内容,该命令会把\n、\r回车删除,结果不会显示,用ctrl+d结束以后才会显示结果
[root@centos7 data]#tr -dc '[:alpha:]' a1b2c3d4e5 输入内容 abcde[root@centos7 data]# 按ctrl+d,显示结果
-
常用选项:
[:alnum:]:字母和数字
[:alpha:]:字母
[:cntrl:]:控制(非打印)字符
[:digit:]:数字
[:graph:]:图形字符
[:lower:]:小写字母
[:print:]:可打印字符
[:punct:]:标点符号
[:space:]:空白字符
[:upper:]:大写字母
[:xdigit:]:十六进制字符
知识扩展:
tr -d '\n' < 文件名 把windows文件转换为linux文件(把windows文件中的换行符去掉)
转换小工具(需要安装软件包才能使用)
dos2unix windows文件转换为linux文件
unix2dos linux文件转换为windows文件
练习:
以下结果不同的是哪一项(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
从文件中导入STDIN,即标准输入重定向
- 使用 < 来重定向标准输入
- 某些命令能够接受从文件中导入的STDIN
tr ‘a-z’ ‘A-Z’< /etc/issue
该命令会把/etc/issue中的小写字符都转换成大写字符[root@centos7 ~]#tr 'a-z' 'A-Z' < /etc/issue \S KERNEL \R ON AN \M
- tr -d abc < /date/f2 删除f2文件中的所有abc中任意字符
[root@centos7 data]#cat f2 abcdefgh [root@centos7 data]#tr -d abc < /data/f2 defgh
- cat > file 把file文件内容输入给cat命令
按ctrl+d离开,可以使用文件来代替键盘的输入[root@centos7 data]#cat >file 123 abcd [root@centos7 data]#cat file 123 abcd
- Cat > filea < fileb 把filea文件内容输入给cat,然后把cat结果重定向到fileb文件
[root@centos7 data]#cat f1 f2 1234567 abcde [root@centos7 data]#cat > f1 < f2 [root@centos7 data]#cat f1 f2 abcde abcde
把多行发送给STDIN,即多行内容重定向
- 使用“<<终止词”命令从键盘把多行重导向给STDIN
直到 终止词 位置的所有文本都发送给STDIN
有时被称为就地文本(heretext)
示例:mail -s "Please Call" admin@magedu.com <<END > Hi Wang, > how are you? > END
3、管道
- 管道(使用符号“|”表示)用来连接命令
命令1 | 命令2 | 命令3 | …
将命令1的STDOUT发送给命令2的STDIN,命令2的STDOUT发送到命令3的STDIN
STDERR默认不能通过管道转发,可利用2>&1 或 |& 实现
最后一个命令会在当前shell进程的子shell进程中执行用来
组合多种工具的功能
ls | tr 'a-z' 'A-Z'[root@centos7 data]#ls f1 f2 f3 file [root@centos7 data]#ls | tr 'a-z' 'A-Z' F1 F2 F3 FILE
- less :一页一页地查看输入
ls -l /etc | less
知识扩展:
echo {1..100} |tr ' ' +|bc 1加到100
[root@centos7 data]#echo {1..100} |tr ' ' +|bc 把数字间的空格替换为加号用bc计算
5050
管道中 - 符号
- 示例:
将/home 里面的文件打包,但打包的数据不是记录到文件,而是传送到stdout,经过管道后,将tar -cvf-/home 传送给后面的tar -xvf-,后面的这个-则是取前一个命令的stdout,因此,就不需要使用临时file了 - tar -cvf - /home | tar -xvf -
tee 重定向到多个目标
- 命令1 | tee [-a ] 文件名 | 命令2
把命令1的STDOUT保存在文件中,做为命令2的输入
-a 追加[root@centos7 data]#ls f1 f2 f3 file [root@centos7 data]#ls |tee -a test | tr 'a-z' 'A-Z' F1 F2 F3 FILE [root@centos7 data]#cat test f1 f2 f3 file
- 功能:
保存不同阶段的输出
复杂管道的故障排除
同时查看和记录输出
练习:
1、将/etc/issue文件中的内容转换为大写后保存至/tmp/issue.out文件中
cat /etc/issue | tr 'a-z' 'A-Z' >>/tmp/issue.out
或 tr [:lower:] [:upper:]< /etc/issue >> /tmp/issue.out
2、将当前系统登录用户的信息转换为大写后保存至/tmp/who.out文件中
who | tr [:lower:] [:upper:]>>/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 $USER ,the system version is here,please help me to check it,thanks!
cat /etc/centos-release
EOF
4、将/root/下文件列表,显示成一行,并文件名之间用空格隔开
/root目录下每个文件实际上都是单独一行,因此要去掉换行符即可
ls /root|tr -s '\n' ' ' 或ls /root |tr '\n' ' '
5、计算1+2+3+..+99+100的总和
echo {1..10}|tr ' ' '+'|bc
6、删除Windows文本文件中的‘^M’字符
tr -d '\r' < win.txt
注意:win.txt是windows文件
7、处理字符串“xt.,l 1 jr#!$mn 2 c*/fe 3 uz 4”,只保留其中的数字和空格
echo 'xt.,l 1 jr#uzmn 2 c*/fe 3 uz 4' |tr -dc '[:digit:][:space:]'
8、将PATH变量每个目录显示在独立的一行
echo $PATH | tr ':' '\n'
9、将指定文件中0-9分别替代成a-j
tr -t '0-9' 'a-j' < file.txt
10、将文件/etc/centos-release中每个单词(由字母组成)显示在独立的一行,并无空行
tr -sc '[:alpha:]' '\n' </etc/centos-release
或 cat /etc/centos-release|tr -sc '[:alpha:]' '\n'
文章评论