Linux

【シェル】curlコマンドで&以降のクエリが認識されない

表題の通りなのですが、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

まとめ

ポイントしては以下になるかなと思います。

シェルで引数を文字列として扱う場合、ダブルクォーテーションで囲う

ここまで読んでいただきありがとうございました。

ABOUT ME
sakai
東京在住の30歳。元々は車部品メーカーで働いていてましたが、プログラミングに興味を持ちスクールに通ってエンジニアになりました。 そこからベンチャー → メガベンチャー → 個人事業主になりました。 最近は生成 AI 関連の業務を中心にやっています。 ヒカルチャンネル(Youtube)とワンピースが大好きです!