IO 重定向和管道

1. IO 重定向和管道

1.1 标准输入和输出

程序:指令+数据

读入数据:Input

输出数据:Output

打开的文件都有一个fd: file descriptor (文件描述符)

Linux给程序提供三种 I/O 设备

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

例:文件描述符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[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
命令 操作符号 文件名 

支持的操作符

1
2
3
4
1> 或 > 把STDOUT重定向到文件
2> 把STDERR重定向到文件
&> 把标准输出和错误都重定向
>& 和上面功能一样,建议使用上面方式

以上如果文件已存在,文件内容会被覆盖

1
2
3
set -C 禁止将内容覆盖已有文件,但可追加, 利用 >| 仍可强制覆盖
 
set +C 允许覆盖,默认

追加

>> 可以在原有内容基础上,追加内容

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

1
2
>> 追加标准输出重定向至文件
2>> 追加标准错误重定向至文件

标准输出和错误输出各自定向至不同位置

1
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:

1
2
[root@centos7 ~]#ls 1> /dev/pts/1
[root@centos7 ~]#ls /data > /dev/pts/1

例2:标准错误重定向

1
[root@centos7 ~]#rm /data/f1.log 2> /data/all.log

例3:合并多个命令的结果至一个文件中

1
2
[root@centos7 ~]#( cal 2019 ; cal 2020 ) > all.txt
[root@centos7 ~]#{ ls;hostname;} > /data/all.logl  

例4:清理大文件

1
2
cat /dev/null > /data/file.log
> /data/file.logl 

例5:分别重定向

1
[root@centos7 ~]#ls /data/ /xxoo > stdout.log 2> stderr.log 

例6:标准重定向和错误重定向放到同一个文件

1
2
3
4
5
[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:

1
2
3
[root@centos7 ~]#man bash > bash.txt
[root@centos7 ~]#wc -l bash.txt
3902 bash.txtl 

例8: 输入密码不提示

1
[root@centos7 ~]#passwd test &> /dev/null

例9: 实现标准输出和错误的互换

1
2
3
4
5
6
7
8
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 转换和删除字符

1
tr [OPTION]... SET1 [SET2] 

选项-d --delete:删除所有属于第一字符集的字符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
-s --squeeze-repeats:把连续重复的字符以单独一个字符表示,即去重
-t --truncate-set1:将第一个字符集对应字符转化为第二字符集对应的字符
-c –C --complement:取字符集的补集<br>
\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:]:空白字符<br>[:print:]:可打印字符<br>[:punct:]:标点符号<br>[:graph:]:图形字符<br>[:cntrl:]:控制(非打印)字符<br>[:xdigit:]:十六进制字符

例子1  

1
2
3
#该命令会把/etc/issue中的小写字符都转换成大写字符<br>tr‘a-z’ ‘A-Z’</etc/issue
#删除fstab文件中的所有abc中任意字符
tr–dabc</etc/fstabl

例子2

1
2
3
4
5
6
7
8
9
10
11
12
13
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#将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标准输入重定向
实现标准输入重定向的符号

1
2
3
4
5
COMMAND0<FILE
COMMAND<FILE
比如:
cat >file <br>mage
hostname

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

1
2
cat < file1 > file2
cat < file1 >> file1a 

 1.2.2.3 把多行重定向

 

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

 

其中终止词可以是任何一个或多个符号,比如:!,@,$,EOF(End Of File),其中EOF比较常用
 
范例:
1
2
3
4
5
6
7
8
9
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
命令1 | 命令2 | 命令3 | ... 

  

管道符说明:

    1.将命令1的STDOUT发送给命令2的STDIN,命令2的STDOUT发送到命令3的STDIN

    2.所有命令会在当前shell进程的子shell进程中执行

    3.组合多种工具的功能  

注意: STDERR默认不能通过管道转发,可利用2>&1或|&实现,如

1
2
命令1 2>&1 | 命令2
命令1 | & 命令2a 

案例1:  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[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:

1
2
3
4
5
6
7
8
#转换为大写字母
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
命令1 | tee [-a ] 文件名 | 命令2 

以上可以把命令1的STDOU保存在文件中,作为命令2的输入

选项:

1
-a  追加

功能  

1.保存不同阶段的输出

2.复杂管道的故障排除

3.同时查看和记录输出

例:

1
2
3
4
5
6
7
8
[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 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[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了
1
tar -cvf - /home | tar -xvf -

  

  

 

 

 

 

 

  

 

 

  

posted @   jefferyone  阅读(44)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示