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 把多行重定向

 

使用 "<<终止词" 命令从键盘把多行重导向给STDIN,直到终止词位置之前的所有文本都发送给STDIN,有时被称为就地文本(here documents)

 

其中终止词可以是任何一个或多个符号,比如:!,@,$,EOF(End Of File),其中EOF比较常用
 
范例:
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.3.1 管道
管道(使用符号“|”表示)用来连接多个命令
格式
命令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.3.2 tee 命令
利用 tee 命令可以重定向到多个目标,经常配合管道符一起使用

格式

命令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

 

1.4 重定向中的 - 符号

重定向有时会使用符号

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

  

  

 

 

 

 

 

  

 

 

  

posted @ 2022-04-29 12:19  jefferyone  阅读(54)  评论(0)    收藏  举报