表題の通りなのですが、curlコマンドを打った際にクエリパラメータが認識されず、ハマってしまったのでシェルについて調べたのをまとめたいと思います。
結論としては、curlコマンドでURLを叩く際にはダブルクォーテーションで括ったほうがベターです。その理由について書いていきます。
ダブルクォーテーションで囲う理由
curlコマンドは引数の文字列をダブルクォーテーションで囲わなくても正常に動きます。では、なぜ囲ったほうがいいのかというと、シェルでは&が複数コマンドの実行制御に使われるからです。
下の例では複数のクエリパラメータを&でつないでいます。これでは、width以降はcurlコマンドの引数として扱われなくなります。理由は&がコマンド連結の構文として解釈されているからです。
curl "http://localhost:8080/generate?url=https://google.com&width=200&height=200
echoを使って、動作確認した結果です。これにより、スペースが空いていなくても&はコマンド制御に使われていることが分かります。
$ echo Hello & echo World
World
Hello
$ echo Hello&echo World
World
Hello
これを防ぐための方法がダブルクォーテーション(“”)で囲うという方法だったわけです。
echo "Hello&echo World"
Hello&echo World
各実行制御構文の意味
補足として、せっかく&が出てきたので他の構文も見ておきます。
;(セミコロン)
前のコマンドが終わり次第、次のコマンドが実行される。
$ (sleep 1; echo Hello) & echo WorldHello
Hello
World
&(アンパサンド)
コマンド1とコマンド2を同時に実行する。
実際にはあまり使われることはなさそう。
$ (sleep 1; echo Hello) & echo World
World
# 1s後に出力される
Hello
&&
コマンド1が正常に終了したときのみコマンド2を実行する。
Dockerfileなどでよく見る構文かと思いますが、ダウンロードなどを行う場合これがよく使われます。(失敗しているのに次に行きたくないですからね)
$ echo Hello && echo World
Hello
World
||
コマンド1が正常終了しなかった場合のみコマンド2を続行する。
エラーハンドリングで使われそう。
$ echo Hello || echo World
Hello
まとめ
ポイントしては以下になるかなと思います。
シェルで引数を文字列として扱う場合、ダブルクォーテーションで囲う
ここまで読んでいただきありがとうございました。