web-dev-qa-db-ja.com

curl経由で投稿されるエスケープ文字列

私は、いくつかのatomフィードを受け取り、それらを Slack API を介してslackにポストするスクリプトをcurlを介して作成しようとしています。単純なテキストの場合、それらの一部には二重引用符または&文字が含まれており、invalid payloadエラーが発生するため、Slack APIが煩わしいようです。スクリプトは次のとおりです。

#!/bin/bash
rsstail -i 3 -u "http://MY_FEED_URL" -n 0 | while read line;
do
    # This is just a sample text, it should be ${line}
    data='Something "&" and something do " "';
    payload="payload={\"channel\": \"#my_channel\", \"username\": \"Bot\", \"text\": \"${data}\", \"icon_emoji\": \":ghost:\"}";
    echo ${payload};
    curl \
        -H "Accept: application/json" \
        -X POST \
        -d '${payload}' \
        https://hooks.slack.com/services/xxxx

「エコー」の出力は次のとおりです。

payload={"channel": "#my_channel", "username": "Bot", "text": "Something "&" and something do " "", "icon_emoji": ":ghost:"}

私はbashスクリプトの知識がなく、少し助けが必要です。何が悪いのですか?

ありがとう!

4
Comforse

データをURLエンコードする必要があります。これを行う最も簡単な方法は、-dオプションを--data-urlencodeで置き換えることにより、curlにそれを実行させることです。また、二重引用符を使用する必要があります。そうしないと、シェルは変数を展開しません。そのため、

curl \
    -H "Accept: application/json" \
    -X POST \
    --data-urlencode "${payload}" \
    https://hooks.slack.com/services/xxxx

payload=のように、パーツ間にスペースがない場合は、文字列の一部を一重引用符で囲み、二重引用符で囲むことにより、'...'"..."'...'の設定を簡略化することもできます。つまり、

payload='payload={"channel": "#my_channel", "username": "Bot", "text": "'"${data}"'", "icon_emoji": ":ghost:"}'

おそらく、dataの二重引用符をエスケープする必要があります。おそらく、json文字列の\の内側にあるため、""を使用します。

data='Something \"&\" and something do \" \"'

入力から変数lineにデータを読み込んだ場合は、bashでこの置換を行うことができます。

line=${line//\"/\\\"}
8
meuh