Bash脚本中curl命令引号内变量引用的问题解决
问题描述
我之前查过类似问题,以为找到了解决方案,但这个方案时好时坏,现在完全用不了,很困惑。
我需要用curl发送以下POST请求到API:
curl -X POST https://example.com/ppn -d 'param_one=87,a1b2c3d4&format=json¶m_two=23,12,14¶m_three=param_four¶m_five=G&value=Password.123'
这条命令在命令行里执行完全正常。现在我要把其中的Password.123替换成从config.json读取的变量$pass1。
我参考同类问题试了下面的写法:
#!/bin/bash pass1=$( jq -r '.[] | .pass1' config.json; ) curl -X POST https://example.com/ppn -d 'param_one=87,a1b2c3d4&format=json¶m_two=23,12,14¶m_three=param_four¶m_five=G&value="'"$pass1"'"'
但这个方案时好时坏,现在彻底失效了。因为调用的是公共API,没法查看错误详情。我还试了另外两种写法,都不行:
写法1:
curl -X POST https://example.com/ppn -d "param_one=87,a1b2c3d4&format=json¶m_two=23,12,14¶m_three=param_four¶m_five=G&value='$pass1'"
写法2:
curl -X POST https://example.com/ppn -d 'param_one=87,a1b2c3d4&format=json¶m_two=23,12,14¶m_three=param_four¶m_five=G&value="$pass1"'
试了各种方法都没解决,请问怎么在Bash脚本里用从config.json读取的$pass1变量,生成和原命令一致的curl请求调用API?
解决方案
问题核心是bash的引号处理逻辑错误,原命令中value=Password.123的参数值没有额外引号,所以替换变量时不需要给$pass1添加多余引号,同时要确保变量能被bash正确解析展开。
方法1:双引号包裹整个-d参数
这是最简洁的写法,双引号会让bash自动解析变量,同时保留其他参数的原样:
#!/bin/bash pass1=$(jq -r '.[] | .pass1' config.json) curl -X POST https://example.com/ppn -d "param_one=87,a1b2c3d4&format=json¶m_two=23,12,14¶m_three=param_four¶m_five=G&value=$pass1"
方法2:单引号拼接变量(更直观)
如果担心双引号内的特殊字符干扰,可以拆分成单引号固定静态参数,再拼接变量部分:
#!/bin/bash pass1=$(jq -r '.[] | .pass1' config.json) curl -X POST https://example.com/ppn -d 'param_one=87,a1b2c3d4&format=json¶m_two=23,12,14¶m_three=param_four¶m_five=G&value='"$pass1"
这里的逻辑是:用单引号锁定前面的静态参数,关闭单引号后用双引号包裹$pass1(确保变量正确展开,同时兼容密码中的空格、特殊字符),无需额外添加引号,完全匹配原命令的参数结构。
额外注意:处理密码中的特殊字符
如果$pass1包含&、=、%这类URL特殊字符,必须进行URL编码,否则会导致参数被截断或解析错误。可以用jq的@uri过滤器完成编码:
#!/bin/bash pass1=$(jq -r '.[] | .pass1' config.json) encoded_pass1=$(printf "%s" "$pass1" | jq -sRr @uri) curl -X POST https://example.com/ppn -d "param_one=87,a1b2c3d4&format=json¶m_two=23,12,14¶m_three=param_four¶m_five=G&value=$encoded_pass1"
内容的提问来源于stack exchange,提问作者Trinitron
相关产品推荐
相关产品推荐

