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 把多行重定向
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 | 命令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 | 命令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 | tar -cvf - /home | tar -xvf - |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~