IO 重定向和管道
1. IO 重定向和管道
1.1 标准输入和输出
程序:指令+数据
读入数据:Input
输出数据:Output
打开的文件都有一个fd: file descriptor (文件描述符)
Linux给程序提供三种 I/O 设备
标准输入(STDIN) -0 默认接受来自终端窗口的输入 标准输出(STDOUT)-1 默认输出到终端窗口 标准错误(STDERR) -2 默认输出到终端窗口
例:文件描述符
[root@centos7 ~]#ll /dev/std* lrwxrwxrwx. 1 root root 15 Dec 16 08:56 /dev/stderr -> /proc/self/fd/2 lrwxrwxrwx. 1 root root 15 Dec 16 08:56 /dev/stdin -> /proc/self/fd/0 lrwxrwxrwx. 1 root root 15 Dec 16 08:56 /dev/stdout -> /proc/self/fd/1 [root@centos7 ~]#ll /proc/self/fd/* ls: cannot access '/proc/self/fd/255': No such file or directory lrwx------. 1 root root 64 Dec 16 10:59 /proc/self/fd/0 -> /dev/pts/0 lrwx------. 1 root root 64 Dec 16 10:59 /proc/self/fd/1 -> /dev/pts/0 lrwx------. 1 root root 64 Dec 16 10:59 /proc/self/fd/2 -> /dev/pts/0 lr-x------. 1 root root 64 Dec 16 10:59 /proc/self/fd/3 -> /var/lib/sss/mc/passwd lrwx------. 1 root root 64 Dec 16 10:59 /proc/self/fd/4 -> 'socket:[66542]' lr-x------. 1 root root 64 Dec 16 10:59 /proc/self/fd/5 -> /var/lib/sss/mc/group [root@centos7 ~]#ll /proc/`pidof tail`/fd total 0 lrwx------. 1 root root 64 Dec 16 10:56 0 -> /dev/pts/1 lrwx------. 1 root root 64 Dec 16 10:56 1 -> /dev/pts/1 lrwx------. 1 root root 64 Dec 16 10:56 2 -> /dev/pts/1 lr-x------. 1 root root 64 Dec 16 10:56 3 -> /var/log/messages lr-x------. 1 root root 64 Dec 16 10:56 4 -> anon_inode:inotify
1.2 I/O重定向 redirect
I/O重定向:将默认的输入,输出或错误对应的设备改变,指向新的目标
1.2.1 标准输出和错误重新定向
STDOUT和STDERR可以被重定向到指定文件,而非默认的当前终端
格式:
命令 操作符号 文件名
支持的操作符
1> 或 > 把STDOUT重定向到文件 2> 把STDERR重定向到文件 &> 把标准输出和错误都重定向 >& 和上面功能一样,建议使用上面方式
以上如果文件已存在,文件内容会被覆盖
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/file.out 2>&1
合并多个程序
(CMD1;CMD2......) 或者{ CMD1;CMD2;....; }合并多个程序的STDOUT
例1:
[root@centos7 ~]#ls 1> /dev/pts/1 [root@centos7 ~]#ls /data > /dev/pts/1
例2:标准错误重定向
[root@centos7 ~]#rm /data/f1.log 2> /data/all.log
例3:合并多个命令的结果至一个文件中
[root@centos7 ~]#( cal 2019 ; cal 2020 ) > all.txt
[root@centos7 ~]#{ ls;hostname;} > /data/all.logl
例4:清理大文件
cat /dev/null > /data/file.log > /data/file.logl
例5:分别重定向
[root@centos7 ~]#ls /data/ /xxoo > stdout.log 2> stderr.log
例6:标准重定向和错误重定向放到同一个文件
[root@centos7 ~]#ls /data /xxx > /data/all.log 2>&1 [root@centos7 ~]#ls /data /xxx 2> /data/all.log 1>&2 [root@centos7 ~]#ls /data /xxx &> /data/all.log [root@centos7 ~]#ls /data /xxx 2>&1 > /data/all.log ls: cannot access '/xxx': No such file or directoryl
例7:
[root@centos7 ~]#man bash > bash.txt [root@centos7 ~]#wc -l bash.txt 3902 bash.txtl
例8: 输入密码不提示
[root@centos7 ~]#passwd test &> /dev/null
例9: 实现标准输出和错误的互换
[root@centos7 ~]#ls f1.txt f2.txt ls: cannot access 'f1.txt': No such file or directory ls: cannot access 'f2.txt': No such file or directory [root@centos7 ~]#( cat /etc/centos-release /etc/xxx 3>&1 1>&2 2>&3 ) > f1.txt 2> f2.txt [root@centos7 ~]#cat f1.txt cat: /etc/xxx: No such file or directory [root@centos7 ~]#cat f2.txt CentOS Linux release 7.9.2003 (Core)
1.2.2 标准输入重定向
从文件中导入STDIN,代替当前终端的输入设备,使用 < 来重定向标准输入某些命令能够接受从文件中导入的STDIN
1.2.2.1 tr 命令
tr 转换和删除字符
tr [OPTION]... SET1 [SET2]
选项-d --delete:删除所有属于第一字符集的字符
-s --squeeze-repeats:把连续重复的字符以单独一个字符表示,即去重 -t --truncate-set1:将第一个字符集对应字符转化为第二字符集对应的字符 -c –C --complement:取字符集的补集
\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 [:alnum:]:字母和数字 [:alpha:]:字母 [:digit:]:数字 [:lower:]:小写字母 [:upper:]:大写字母 [:space:]:空白字符
[:print:]:可打印字符
[:punct:]:标点符号
[:graph:]:图形字符
[:cntrl:]:控制(非打印)字符
[:xdigit:]:十六进制字符
例子1
#该命令会把/etc/issue中的小写字符都转换成大写字符
tr‘a-z’ ‘A-Z’</etc/issue #删除fstab文件中的所有abc中任意字符 tr–dabc</etc/fstabl
例子2
root@centos7~]#df | tr -s ' ' : Filesystem:1K-blocks:Used:Available:Use%:Mounted:on devtmpfs:910220:0:910220:0%:/dev tmpfs:900:0:924732:0%:/dev/shm tmpfs:924732:9964:914768:2%:/run tmpfs:924732:0:924732:0%:/sys/fs/cgroup /dev/sda2:104806400:5256556:99549844:6%:/ /dev/sda3:52403200:398588:52004612:1%:/data /dev/sda1:999320:131768:798740:15%:/boot tmpfs:184944:16:184928:1%:/run/user/42 tmpfs:184944:4:184940:1%:/run/user/0 tmpfs:184944:4656:180288:3%:/run/user/1000 /dev/sr0:6967726:6967726:0:100%:/run/media/wang/CentOS-8-BaseOS-x86_64
例子3
#将windows的文本转化为Linux的文本格式 [root@centos7~]#catwindows.txt a b c[root@centos7~]#filewindows.txt windows.txt:ASCIItext,withCRLFlineterminators [root@centos7~]#hexdump-Cwindows.txt 00000000 610d0a620d0a63 |a..b..c|00000007 [root@centos7~]#nanolinux.txt [root@centos7~]#hexdump-Clinux.txt 00000000 610a620a630a |a.b.c.| 00000006 [root@centos7~]#tr-d'\r'<windows.txt>windows2.txt [root@centos7~]#hexdump-Cwindows2.txt 00000000 610a620a63 |a.b.c| 00000005 [root@centos7~]#filewindows2.txt windows2.txt:ASCIItext
1.2.2.2标准输入重定向
实现标准输入重定向的符号
COMMAND0<FILE COMMAND<FILE 比如: cat >file
mage hostname
按ctrl+d离开,可以使用文件来代替键盘的输入
cat < file1 > file2 cat < file1 >> file1a
1.2.2.3 把多行重定向
mail -s "Please Call" admin@hostname <<EOF > Hi hostname > > Please give me a call when you get in. We may need > to do some maintenance on server1. > > Details when you're on-site > admin > EOF
1.3 管道
命令1 | 命令2 | 命令3 | ...
管道符说明:
1.将命令1的STDOUT发送给命令2的STDIN,命令2的STDOUT发送到命令3的STDIN
2.所有命令会在当前shell进程的子shell进程中执行
3.组合多种工具的功能
注意: STDERR默认不能通过管道转发,可利用2>&1或|&实现,如
命令1 2>&1 | 命令2 命令1 | & 命令2a
案例1:
[root@centos7 ~]#ls /data /xxx | tr 'a-z' 'A-Z' ls: cannot access '/xxx': No such file or directory /DATA: ALL.LOG F1.TXT PASSWD.LOG STERR.LOG STOUT.LOG TEST.LOG TOUCH.LOG [root@centos7 ~]#ls /data /a.logs 2>&1 | tr 'a-z' 'A-Z' LS: CANNOT ACCESS '/a.logs': NO SUCH FILE OR DIRECTORY /DATA: ALL.LOG F1.TXT PASSWD.LOG STERR.LOG STOUT.LOG TEST.LOG TOUCH.LOG [root@centos7 ~]#ls /data /a.log |& tr 'a-z' 'A-Z' LS: CANNOT ACCESS '/XXX': NO SUCH FILE OR DIRECTORY /DATA: ALL.LOG F1.TXT PASSWD.LOG STERR.LOG STOUT.LOG TEST.LOG TOUCH.LOG
案例2
[root@centos7 ~]#passwd --stdin tests Changing password for user tests. magedu passwd: all authentication tokens updated successfully. [root@centos7 ~]#cat pass.txt centos [root@centos7 ~]# passwd --stdin tests < pass.txt Changing password for user tests. passwd: all authentication tokens updated successfully. [root@centos7 ~]#cat pass.txt | passwd --stdin tests Changing password for user wang. passwd: all authentication tokens updated successfully. [root@centos7 ~]#echo magedu | passwd --stdin tests Changing password for user tests. passwd: all authentication tokens updated successfully. [root@centos7 ~]#echo magedu | passwd --stdin tests &> /dev/null
案例3:
#转换为大写字母 ls | tr 'a-z' 'A-Z' #less实现分页查看输入 ls -l /etc | less #mail 通过电子邮件发送输入 echo "test email" | mail -s "test" test@example.com #算术运算 echo "2^3" |bc
格式
命令1 | tee [-a ] 文件名 | 命令2
以上可以把命令1的STDOU保存在文件中,作为命令2的输入
选项:
-a 追加
功能
1.保存不同阶段的输出
2.复杂管道的故障排除
3.同时查看和记录输出
例:
[root@centos7 ~]#echo {1..100}|tr ' ' +|bc
5050
[root@centos7 ~]#echo {1..100..2} | tr ' ' + | bc
2500
[root@centos7 ~]#seq -s + 1 100 |bc
5050
[root@centos7 ~]#seq -s+ 1 2 100 | bc
2500l
例
[root@centos7 ~]#cat <<EOF | tee test.txt > set from=84758750@qq.com > set smtp=smtp.qq.com > set smtp-auth-user=84758750@qq.com > set smtp-auth-password=cszzb > set smtp-auth=login > set ssl-verify=ignore > EOF [root@centos7 ~]#cat test.txt set from=84758750@qq.com set smtp=smtp.qq.com set smtp-auth-user=84758750@qq.com set smtp-auth-password=cszzb set smtp-auth=login set ssl-verify=ignore
重定向有时会使用符号
tar -cvf - /home | tar -xvf -

浙公网安备 33010602011771号