模块S09 进程、管道与重定向篇号S09-01 / 42预计阅读45 分钟主线Bash文章目录本篇目标30 秒速览正文1. 三个标准流2. 输出重定向 与 3. 标准错误24. 合并 stderr 到 stdout215. Bash 与 6. 丢弃输出/dev/null7. 输入重定向8. here-doc 加厚衔接 S02-028.1 引号定界符8.2 结束标记8.3 -忽略前导 Tab8.4 常见用途9. 重定向与单词位置10. 读脚本时的常见模式10.1 日志分流10.2 静默检查10.3 临时 here-doc 配置10.4 别和数值比较混淆11. 注意点小结读脚本检查清单练习判断题实操题改错题here-doc 题下一篇预告本篇目标掌握 Shell重定向把命令的标准输入/输出/错误接到文件或丢弃。会写221、输入重定向以及here-doc与here-string。能读懂日志分流、/dev/null静音、生成配置文件等常见写法并避开与21顺序等经典坑。30 秒速览默认0标准输入、1标准输出、2标准错误终端上常混在一起显示。覆盖写 stdout追加2只重定向 stderr。21把 stderr接到stdout 当前去向常写作file 21让两者进同一文件。Bashstdout 与 stderr 一起重定向到文件。 file用文件作命令 stdinS07-02while read常配合。here-docTAG多行文本作输入TAG不展开变量S02-02 初识本篇加厚。正文1. 三个标准流描述符名称默认0stdin键盘 / 管道输入1stdout终端2stderr终端ls/etcls/nosuch# 错误信息走 stderr成功列表走 stdout读脚本日志、错误是否分开文件是否都丢弃到/dev/null。2. 输出重定向与echohelloout.txt# 覆盖写 stdoutechoworldout.txt# 追加运算符行为截断文件再写覆盖在文件末尾追加目标文件由 Shell 先打开再启动命令即使命令失败文件可能已被清空覆盖时需注意。# 错以为只有成功才写文件result$(cmd)log.txt# 重定向的是 echo/赋值整条实际需cmdlog.txtnoclobberset -o noclobber禁止覆盖已存在文件强制用|Bash覆盖。3. 标准错误2greppattern missing.txt2err.log只把stderr写入err.logstdout仍在终端。cmdout.log2err.log成功输出与错误信息分文件保存运维脚本常见。4. 合并 stderr 到 stdout2121表示fd 2stderr复制fd 1stdout的当前指向。cmdall.log21含义先把 stdout 接到all.log再把 stderr 也接到同一位置。日志里既有正常输出也有错误。顺序很重要# 对stderr 跟随 stdout 进 merged.logcmdmerged.log21# 错先 21 时 stdout 还在终端stderr 接到终端再 只改 stdoutcmd21merged.log# 结果merged.log 往往只有 stdoutstderr 仍在终端读脚本时见到21从左到右看重定向顺序。5. Bash与cmdall.log# stdout stderr → all.log覆盖cmdall.log# 追加等价于 all.log 21覆盖场景。可读性更好但POSIX sh 不一定支持Bash 脚本常用。6. 丢弃输出/dev/nullcmd/dev/null# 丢掉 stdoutcmd2/dev/null# 丢掉 stderrcmd/dev/null# 全丢cmd/dev/null21# 全丢常见写法「只要退出码、不要输出」ifgrep-qpatternfile2/dev/null;thenechofoundfiS07-02until ping ... /dev/null 21同理。7. 输入重定向wc-ldata.txt文件内容作stdin不增加wc的参数与wc data.txt统计方式类似实现路径不同。while read惯用法S07-02whileIFSread-rline;doecho$linedonedata.txthere-string单行greppattern$var8. here-doc加厚衔接 S02-02catEOFconfig.ini[main] user$USERdebug1 EOF多行文本作为stdin传给cat或tee、psql等。 config.ini可写在EOF同一行或 here-doc 结束后重定向习惯写在同一行。8.1 引号定界符catEOF PATH$PATH EOF# 输出字面 PATH$PATH定界符展开EOF展开$变量、cmd、\EOF/EOF字面文本8.2 结束标记结束行EOF必须单独一行、顶格、与开头TAG 完全一致除非用-。# 错行首有空格EOF8.3-忽略前导 Tabiftrue;thencat-EOF indented line EOFfi行首的Tab会被剥掉空格不行便于在if/函数里缩进书写。8.4 常见用途# 生成脚本片段catSHhelper.sh#!/usr/bin/env bash echo generated SHchmodx helper.sh# 传多行给命令diff-u/etc/hosts -EOF 127.0.0.1 localhost EOF与注释区别here-doc 是数据会进入命令或文件S02-02。9. 重定向与单词位置重定向可出现在命令前、中、后Shell 在执行命令前统一处理out.txtechohiechohiout.txt二者等价。读脚本时别被顺序迷惑。多个重定向cmd0in.txt1out.txt2err.txt数字显式指定 fd进阶知道即可。10. 读脚本时的常见模式10.1 日志分流exec(tee-arun.log)21# 进阶进程替换S09-04# 简单版./job.shjob.out2job.err10.2 静默检查test-f$f2/dev/null10.3 临时 here-doc 配置python3PY import sys print(sys.version) PY10.4 别和数值比较混淆# 错在 [[ 里把 当大于号[[$n10]]# 对((n10))在命令上下文里是重定向S05-03、S05-04。11. 注意点小结点说明 file 21顺序先定 stdout 去向再合并 stderr覆盖失败命令也可能已清空文件引号 here-doc要字面$用TAG权限重定向由 Shell 开文件注意目录可写管道与重定向组合见S09-02读脚本检查清单stdout / stderr 是分开还是21合并21在前面还是后面静音是否误用 /dev/null却忘了 stderrhere-doc 是TAG还是TAGwhile read ... done file是否比管道更合意S07-02练习判断题cmd 21 out.log与cmd out.log 21效果一定相同。在文件末尾追加不截断原内容。EOF中的$HOME会展开。cmd log在 Bash 中可把 stdout 和 stderr 都写入log。grep x f与grep x f在读文件时行为相近但重定向版不把文件名传给grep作参数。参考答案错顺序不同stderr 未必进 out.log。对。错。对。对。实操题写命令运行ls /etc /nosuch把标准输出写入out.txt标准错误写入err.txt路径不存在时ls仍会部分成功。参考答案ls/etc /nosuchout.txt2err.txt改错题#!/usr/bin/env bashLOGrun.log{echostartfalseechoend}21$LOGcat$LOG期望LOG里既有start也有false的错误但实际可能只有start。参考{echostartfalseechoend}$LOG21或{ ...; } $LOG。先再21。here-doc 题下面会输出什么x42catEOF x$xEOFcatEOF x$x EOF参考答案x42 x$x下一篇预告S09-02《管道与管道退出码pipefail再探》—cmd1 | cmd2、|与$?在管道中的含义。