当变量中的JSON数据包含空格时,cURL引发全局错误

tec*_*aku 1 bash json curl

在Ubuntu 16.04.2 LTS上使用bash v4.3.48(1)和在macOS Sierra 10.12.5上使用bash v3.2.57,我有以下代码可将JSON数据发布到变量中:

#1    
JSON_DATA="Test"; \
curl -X POST "https://www.techotaku.com/json.php" \
    -H "Content-Type: application/json" \
    -d '{"data":"'$JSON_DATA'"}'
Run Code Online (Sandbox Code Playgroud)

返回:

Array
(
    [data] => Test
)
Run Code Online (Sandbox Code Playgroud)

但是,如果$ JSON_DATA包含空格...

#2
JSON_DATA="A Test"; \
curl -X POST "https://www.techotaku.com/json.php" \
    -H "Content-Type: application/json" \
    -d '{"data":"'$JSON_DATA'"}'
Run Code Online (Sandbox Code Playgroud)

...它抛出一个错误:

curl: (3) [globbing] unmatched close brace/bracket in column 6
Run Code Online (Sandbox Code Playgroud)

我以为这可能是因为引号使用不正确,但是如果我回显JSON数据...

echo '{"data":"'$JSON_DATA'"}'
Run Code Online (Sandbox Code Playgroud)

...看起来格式正确:

{"data":"A Test"}
Run Code Online (Sandbox Code Playgroud)

另外,如果我将JSON数据作为字符串而不是变量包括在内,则它可以工作。

#3
curl -X POST "https://www.techotaku.com/json.php" \
    -H "Content-Type: application/json" \
    -d '{"data":"A Test"}'
Run Code Online (Sandbox Code Playgroud)

如果变量包含空格,则使它起作用的唯一方法是将JSON数据括在双引号中,并在字符串中转义文字双引号:

#4    
JSON_DATA="A Test"; \
curl -X POST "https://www.techotaku.com/json.php" \
    -H "Content-Type: application/json" \
    -d "{\"data\":\"$JSON_DATA\"}"
Run Code Online (Sandbox Code Playgroud)

我本以为所有四个例子都行得通。因此,有人可以阐明为什么只有示例1,3和4起作用而示例2却不起作用吗?

非常感谢,史蒂夫。

ran*_*mir 5

您应该引用变量以防止单词被shell分割。您的第二个示例:

'{"data":"'$JSON_DATA'"}'
Run Code Online (Sandbox Code Playgroud)

不起作用,因为它被扩展bash为两个词:

{"data":"A Test"}
Run Code Online (Sandbox Code Playgroud)

因此,-doption接收2个参数({"data":"ATest"})。如果JSON_DATA包含通配符,则将导致文件名扩展。

要修复它,请引用它:

'{"data":"'"$JSON_DATA"'"}'
Run Code Online (Sandbox Code Playgroud)

请注意使用交替的单引号和双引号。这将扩展为一个单词:

{"data":"A Test"}
Run Code Online (Sandbox Code Playgroud)

这是我前一段时间写的一个更详细的答案,其中还提到了另一个方便的选择,即使用here-document。