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
三重出身の28歳。前職はメーカーで働いていて、プログラミングスクールに通って未経験からWeb業界に転職しました。Railsをメインで使っていて、AWSも少しできます。音楽を聞くこととYoutubeを見るのが好きです。最近はへきトラ劇場にハマってます

COMMENT

メールアドレスが公開されることはありません。