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

Bash脚本中字符串比较失效问题排查

问题描述

编写的Bash脚本如下:

set -x

myJson="echo '{\"data\":\"true\"}'"

commandOutput=$(eval $myJson | jq '.data')

echo $commandOutput

while :
do
    if [[ $commandOutput == "true" ]]
    then
        break
    fi
    sleep 1
done

echo "Done"

脚本中的字符串比较始终不生效,只有将比较条件改为'\"true\"'时才能正常工作。开启set -x调试后输出如下:

+ myJson='echo '\''{"data":"true"}'\'''
++ eval echo ''\''{"data":"true"}'\'''
+++ echo '{"data":"true"}'
++ jq .data
+ commandOutput='"true"'
+ echo '"true"'
"true"
+ :
+ [[ "true" == \t\r\u\e ]]
+ sleep 1
+ :
+ [[ "true" == \t\r\u\e ]]
+ sleep 1
+ :
+ [[ "true" == \t\r\u\e ]]
+ sleep 1

看起来比较条件右侧的字符串总是被转义,请问这是什么原因?

原因分析
  1. 从调试输出能明确看到,commandOutput的实际值是"true"(包含双引号),而你的比较条件[[ $commandOutput == "true" ]]中,双引号会被Bash解析移除,实际是拿带引号的"true"和不带引号的true做比较,自然不相等。
  2. 调试日志里的[[ "true" == \t\r\u\e ]]是set -x的特殊显示方式,它把字符串true的每个字符转义显示了,并不是条件本身被转义,本质还是值不匹配导致比较失败。
  3. 另外,你用eval构造命令的方式不仅容易引发转义问题,还存在安全风险,这也是导致后续字符串处理混乱的根源之一。
解决方案

方案1:匹配带引号的目标值

直接把比较条件改成匹配带引号的字符串,用单引号包裹避免转义:

if [[ $commandOutput == '"true"' ]]

方案2:用jq的原始输出(推荐)

使用jq的-r参数(raw output),让它输出不带引号的原始字符串,这样后续比较无需处理引号:

# 去掉不必要的eval,直接构造JSON字符串
commandOutput=$(echo '{"data":"true"}' | jq -r '.data')

# 此时直接比较true即可
if [[ $commandOutput == "true" ]]

如果必须保留myJson变量的写法,也可以去掉eval,改用更安全的方式:

myJson='{"data":"true"}'
commandOutput=$(echo "$myJson" | jq -r '.data')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 01:06:09