curl:在 bash 中添加字符串作为选项

curl:在 bash 中添加字符串作为选项

我想将变量字符串传递给 curl 中的命令选项。

if [ ! -z ${picture} ]; then APISTRING+="--data-urlencode \"picture=${picture}\" ";fi
if [ ! -z ${additional} ]; then APISTRING+="--data-urlencode \"additional_info="${additional}"\" ";fi

因此,如果图片和附加信息不为空,则 $APISTRING 应该是:

--data-urlencode "picture=someinfo"  --data-urlencode "additional_info=additional infos here"

但是当我调用 curl 时

curl -v -X "POST" --url "https://example.org/api" -H "Content-Type: application/x-www-form-urlencoded; charset=utf-8" "${APISTRING}"

它给出了类似的错误

curl:选项--data-urlencode“picture=someinfo”--data-urlencode“additional_info=additional infos here”:未知

有人知道如何处理这个问题吗?

答案1

在变量值中嵌入引号,例如,APISTRING+="--data-urlencode \"picture=${picture}\" "无法正常工作。当您尝试使用时$APISTRING,bash 会在扩展​​变量值之前解析引号,并且在扩展后不会重新扫描“新”引号。因此,引号被视为字符串的一部分,而不是字符串周围的分隔符。

对于此类问题,最好的解决方案是使用数组来存储命令选项:

APISTRING=()
if [ ! -z ${picture} ]; then APISTRING+=(--data-urlencode "picture=${picture}");fi
if [ ! -z ${additional} ]; then APISTRING+=(--data-urlencode "additional_info=${additional}");fi
curl -v -X "POST" --url "https://example.org/api" -H "Content-Type: application/x-www-form-urlencoded; charset=utf-8" "${APISTRING[@]}"

请注意,并非所有 POSIX shell 都支持数组,因此你只应在明确使用 bash 的脚本中使用它(即#!/bin/bash或的 shebang #!/usr/bin/env bash不是 #!/bin/sh[@])。另外,语法非常挑剔;不要在赋值、双引号或扩展数组时遗漏任何括号。

顺便说一句,还有另一种可能的解决方案。您可以使用有条件扩展当场将它们包括进来:

curl -v -X "POST" --url "https://example.org/api" -H "Content-Type: application/x-www-form-urlencoded; charset=utf-8" \
    ${picture:+ --data-urlencode "picture=${picture}"} \
    ${additional:+ --data-urlencode "additional_info=${additional}"}

这里,:+扩展告诉 bash 检查变量是否非空,如果是则不使用它,而是使用备用值:带有适当前缀的变量的引用版本。

答案2

“${APISTRING}”中有不必要的引号:

使固定:

curl -v -X "POST" --url "https://example.org/api" -H "Content-Type: application/x-www-form-urlencoded; charset=utf-8" ${APISTRING}

相关内容