Bash脚本使用命令替换时命令执行顺序异常问题排查
问题分析与解决
异常原因
- 命令替换捕获全部标准输出:主脚本中
checksum=$(subscripts/checksum.sh)的命令替换会将子脚本的所有标准输出(stdout)捕获到变量中,而非实时打印到终端。子脚本里的日志类echo输出都被存入checksum变量,直到主脚本执行echo ${checksum}时才一次性输出,导致主脚本的*** After checksum先于子脚本日志显示。 - 变量引用丢失格式:子脚本中
echo ${diff_res}未加引号,导致diff返回的多行差异内容被压缩成单行,丢失换行格式。 - 输出流未区分:子脚本未将日志信息与需要返回的
diff结果分离,导致日志混入主脚本的变量内容。
修改方案
1. 调整子脚本 subscripts/checksum.sh
将日志输出到标准错误(stderr)避免被命令替换捕获,仅把diff结果输出到标准输出(stdout)供主脚本捕获,同时修正路径问题:
#!/bin/bash # 子脚本位于subscripts目录,直接使用相对路径即可 checksum1=file1.sha512sum.txt checksum2=file2.sha512sum.txt # 日志信息输出到stderr,实时打印到终端 echo "----- Before diff" >&2 # 捕获diff结果并处理退出码 if diff_res=$(diff "$checksum1" "$checksum2"); then echo "Checksums are equal." >&2 echo "$diff_res" else echo "There is a difference between the checksums." >&2 echo "$diff_res" fi echo "----- After diff" >&2
2. 调整主脚本 main.sh
引用变量时加引号保留换行格式,若需允许子脚本返回非零退出码(diff失败时会返回非零),可添加|| true避免set -e终止主脚本:
#!/bin/bash set -e echo "*** Before checksum" # 若需忽略子脚本非零退出码,使用 checksum=$(subscripts/checksum.sh || true) checksum=$(subscripts/checksum.sh) echo "*** After checksum" # 加引号保留diff结果的换行格式 echo "Checksum value: $checksum"
验证结果
执行修改后的脚本,将得到期望的输出:
*** Before checksum ----- Before diff There is a difference between the checksums. ----- After diff *** After checksum Checksum value: 1c1 < a5f4d3e657ad3ef1b208e16f47b6d766cf3e2f1db8d6b5c0d2bf0573d10eb2fefcc75c9f91d5f4e047fa9a7d00848911477005015052f7005a2b85eeb8c4eabf file1.txt --- > 576bfc364f00634e8227f71fdf379168e4c3ee013da9eae2bdcdb905746b8514a959a9c01a8f11b8ea62a67ba08a3041a46b8065b73bdaad754e1d6153131896 file2.txt
内容的提问来源于stack exchange,提问作者dtm_
相关产品推荐
相关产品推荐

