如何检测readarray调用的输入命令是否执行失败?
解决readarray无法捕获子命令执行失败的问题
问题根源
echo $?返回的是readarray自身的退出状态——只要readarray能正常读取输入流(哪怕输入来自一个执行失败的命令),它就会返回0,所以没法直接通过它判断mysql等子命令的执行结果。
方案1:捕获进程替换中子命令的退出码(通用适配readarray场景)
利用临时文件保存子命令的退出状态,父shell读取数组后再读取这个状态:
query="SELECT unknow_column FROM unknow_table;" # 创建临时文件存退出码 tmp_exit_file=$(mktemp) # 在进程替换里执行mysql,执行完立即把退出码写入临时文件 readarray -t queryResultList < <(echo "$query" | mysql -uUSER -pPASSWORD -N; echo $? > "$tmp_exit_file") # 读取退出码并清理临时文件 sub_cmd_exit=$(cat "$tmp_exit_file") rm -f "$tmp_exit_file" # 判断子命令是否失败 if [ "$sub_cmd_exit" -ne 0 ]; then echo "SQL查询执行失败" # 这里添加失败后的处理逻辑,比如退出脚本、打印错误等 else echo "查询成功,结果已存入queryResultList数组" # 处理数组内容,比如遍历输出 # for item in "${queryResultList[@]}"; do echo "$item"; done fi
方案2:先捕获命令输出与退出码,再转数组(更简洁)
先直接执行目标命令,保存其输出和退出码,再将输出转换为数组,避免进程替换的退出码捕获问题:
query="SELECT unknow_column FROM unknow_table;" # 执行mysql命令,捕获输出和退出码 query_output=$(echo "$query" | mysql -uUSER -pPASSWORD -N) sub_cmd_exit=$? if [ "$sub_cmd_exit" -ne 0 ]; then echo "SQL查询执行失败" else # 将输出转换为数组(处理换行分隔的结果) IFS=$'\n' read -r -d '' -a queryResultList <<< "$query_output" echo "查询成功,结果已存入数组" # 示例:遍历数组 # for res in "${queryResultList[@]}"; do echo "$res"; done fi
通用场景说明
上述两种方法都适用于readarray结合其他命令的场景:
- 方案1适合必须用
readarray直接读取输入流的场景,核心是通过临时文件传递子命令的退出码; - 方案2更通用,不管是否用
readarray,都可以先捕获命令的输出和状态,再做后续处理。
内容的提问来源于stack exchange,提问作者Tom's
相关产品推荐
相关产品推荐

