git を使っていて、コミットメッセージとその他の部分を JSON ペイロードとしてサーバーに投稿しています。
現在、私は
MSG=`git log -n 1 --format=oneline | grep -o ' .\+'`
というようにMSGを設定しています。
Calendar can't go back past today
とすると
curl -i -X POST \
-H 'Accept: application/text' \
-H 'Content-type: application/json' \
-d "{'payload': {'message': '$MSG'}}" \
'https://example.com'
私の本当のJSONには、もう2つほどフィールドがあります。
これは問題なく動作しますが、もちろん上記のようなアポストロフィが含まれるコミットメッセージがある場合、JSONは無効となります。
bashで必要な文字をどのようにエスケープすればいいのでしょうか?私はこの言語に詳しくないので、どこから始めればいいのかわかりません。という文字を '
に置き換えることで、最低限のことはできるのではないかと思います。
私もJSONを使った転送のために、Bashで文字をエスケープしようとしていたときに、これに出会いました。特にフリーフォームのテキストを扱おうとしている場合、実際にはもっと大きなエスケープしなければならない文字のリスト – があることを知りました。
私が見つけた便利なTipsは2つあります。
${string//substring/replacement}
構文を使用する。その結果、私が思いついたBashの置換は以下の通りです。
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//\\/\\\\} # \
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//\//\\\/} # /
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//\'/\\\'} # ' (not strictly needed ?)
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//\"/\\\"} # "
JSON_TOPIC_RAW=${JSON_TOPIC_RAW// /\\t} # \t (tab)
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//
/\\\n} # \n (newline)
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//^M/\\\r} # \r (carriage return)
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//^L/\\\f} # \f (form feed)
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//^H/\\\b} # \b (backspace)
この段階では、Unicode文字を正しくエスケープする方法はまだ分かっていません。もしこれがわかったら、私の答えを更新します。
OK、どうすればいいかわかったよ。Bashは予想通りネイティブにサポートしていますが、いつものように構文があまり推測できません
基本的に ${string//substring/replacement}
はイメージ通りのものを返すので、以下のように使うことができます。
MSG=${MSG//\'/\\\'}
というようにします。次の問題は、最初の正規表現が機能しなくなったことですが、これは次のように置き換えることができます。
git log -n 1 --pretty=format:'%s'
結局、エスケープする必要すらありませんでした'。JSONの ' を全て quot;に置き換えただけです。いやー、毎日勉強になりますね。
みたいなのを見つけたんだけど.
MSG=`echo $MSG | sed "s/'/\\\\\'/g"`