You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BASH:如何用trap或命名管道捕获进程替换(tar)的退出码?

捕获进程替换中tar命令的退出码解决方案

你遇到的核心问题是:进程替换<(...)运行在独立子shell中,子shell内赋值的CHECK变量无法传递回父shell,所以父shell里的CHECK为空。下面提供几种不用临时文件的解决方案:

方案1:使用命名管道传递退出码

命名管道是内存级临时通道,不会生成磁盘文件,适合传递退出码这类小数据:

# 创建命名管道
mkfifo tar_exit_pipe

# 后台启动while循环+进程替换,同时将tar退出码写入管道
while IFS= read -r LINE; do
    some_command_processing "$LINE"
done < <(tar PJcvf none.tar.xz /none_exist 2>&1; echo $? > tar_exit_pipe) &

# 从管道读取退出码
CHECK=$(cat tar_exit_pipe)

# 清理命名管道
rm tar_exit_pipe

# 等待后台的while循环执行完毕
wait

echo "tar命令的退出码:$CHECK"

方案2:使用bash协同进程(coproc)

coproc可以同时捕获子进程的输出和退出状态,无需额外管道文件:

# 启动协同进程,执行tar并最后输出退出码
coproc TAR_PROC { tar PJcvf none.tar.xz /none_exist 2>&1; echo $?; }

# 读取协同进程的输出,分离正常日志和退出码
while IFS= read -r LINE <&"${TAR_PROC[0]}"; do
    # 判断是否为数字格式的退出码
    if [[ "$LINE" =~ ^[0-9]+$ ]]; then
        CHECK=$LINE
        break
    fi
    some_command_processing "$LINE"
done

# 关闭协同进程的文件描述符
exec {TAR_PROC[0]}>&-

echo "tar命令的退出码:$CHECK"

方案3:利用文件描述符传递退出码

通过exec创建自定义文件描述符,将退出码从子shell传递到父shell:

# 创建文件描述符,关联到读取退出码的子shell
exec {EXIT_FD}> >(read -r CHECK; : )

# 执行while循环,进程替换内将tar退出码写入文件描述符
while IFS= read -r LINE; do
    some_command_processing "$LINE"
done < <(tar PJcvf none.tar.xz /none_exist 2>&1; echo $? >&$EXIT_FD)

# 关闭文件描述符,触发子shell的read命令完成
exec {EXIT_FD}>&-

echo "tar命令的退出码:$CHECK"

关于trap的说明

trap主要用于捕获信号(比如SIGINT、SIGTERM),无法直接捕获子进程的退出码,因此不适合解决这个问题。

内容的提问来源于stack exchange,提问作者Krzysztof Filipiak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 22:27:21