Bash命令替换在echo中未同行打印结果的原因及替代解法
可复现示例
考虑以下示例:
#!/usr/bin/env bash echo "[Status] $(killall --wait example)"
预期输出:
[Status] example: no process found
实际结果(顺序错误且分为两行):
example: no process found
[Status]
临时解决办法
result=$(killall --wait example 2>&1) echo "[Status] ${result}"
问题解答
1. 为何可复现示例中的输出不在同一行?
killall在找不到目标进程时,会将错误信息输出到标准错误(stderr),而命令替换$(...)仅会捕获标准输出(stdout)。执行原脚本时,子shell中的killall直接将错误信息打印到终端,$(...)捕获到的内容为空,因此echo最终输出仅包含前缀[Status] ,就出现了错误信息先打印、随后打印前缀的分行情况。
2. 除上述临时解决办法外,是否有其他方式等待Command Substitution的结果并同行打印?
有多种替代方式:
- 直接在命令替换内重定向stderr到stdout,写成一行:
echo "[Status] $(killall --wait example 2>&1)" - 使用
sed给输出内容添加前缀,适配多行输出场景:killall --wait example 2>&1 | sed 's/^/[Status] /' - 先打印前缀(不换行),再输出命令结果:
echo -n "[Status] " killall --wait example 2>&1 - 结合管道与
xargs传递结果:killall --wait example 2>&1 | xargs -I {} echo "[Status] {}"
内容的提问来源于stack exchange,提问作者GrabbenD
相关产品推荐
相关产品推荐

