0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

curlコマンドを試しながら学んでみる

Posted at

はじめに

業務でcurlコマンドを使用する必要があるため、その学習メモになります。
実際にコマンドを叩きながらまとめましたので、同じような境遇の方の参考になれば幸いです。

curlとは

正式名称:cURL (Client for URL)

cURL (client for URL)とは、 Linux などの UNIX系OS でよく利用される コマンドラインツール の一つで、 URL で示される ネットワーク 上の場所に対して様々な プロトコル (通信手順)を用いて アクセス できるもの。 MITライセンス に基づき オープンソースソフトウェア として公開されている。

HTTPやFTPなどのプロトコルを使用して、サーバに対してデータの送受信を行うコマンドということがわかります。
curlの使用用途としては、APIを叩いたり、サーバに対してリクエストを行いレスポンスを確認することが多いです。

準備

macOSで実行していきます。

version確認

curlコマンドがインストールされているか確認できます。

curl --version

バージョンが確認できれば準備完了です。

curl 8.7.1 (x86_64-apple-darwin22.0) libcurl/8.7.1 (SecureTransport) LibreSSL/3.3.6 zlib/1.2.11 nghttp2/1.51.0
Release-Date: 2024-03-27
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns ldap ldaps mqtt pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS GSS-API HSTS HTTP2 HTTPS-proxy IPv6 Kerberos Largefile libz MultiSSL NTLM SPNEGO SSL threadsafe UnixSockets

今回の記事では以下のサイトを使用してGET・POSTを試します。
https://httpbin.org/

上記サイトのURLに対してリクエストを行うと、レスポンスを返してくれます。
自分でAPIサーバを作る必要がないので、コマンドを試す際に便利です。

構文とオプション

基本構文

curl [オプション] [URL]

改行したい場合は以下のように\を入れます。

curl -X GET \
> -I 'https://httpbin.org/get'

-X:HTTPリクエストの指定

GET

# デフォルトがGETなので、-Xをつけなくてもいい
curl 'https://httpbin.org/get'

curl -X GET 'https://httpbin.org/get' 
レスポンス
{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/8.7.1", 
    "X-Amzn-Trace-Id": "Root=1-67c90df3-6d2591cb23f7596d5d7dcffe"
  }, 
  "origin": "***.***.***.***", 
  "url": "https://httpbin.org/get"
}

POST

curl -X POST 'https://httpbin.org/post'
レスポンス
{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/8.7.1", 
    "X-Amzn-Trace-Id": "Root=1-67c90ce4-42e4398a0e790f263dbeb372"
  }, 
  "json": null, 
  "origin": "***.***.***.***", 
  "url": "https://httpbin.org/post"
}

-H:ヘッダーの追加

GET

curl -H "content-type: application/json" 'https://httpbin.org/get'
レスポンス
{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Content-Type": "application/json", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/8.7.1", 
    "X-Amzn-Trace-Id": "Root=1-67c94239-6725112e266c77be1904a9f8"
  }, 
  "origin": "***.***.***.***", 
  "url": "https://httpbin.org/get"
}

POST

curl -X POST -H "content-type: application/json" 'https://httpbin.org/post'
レスポンス
# レスポンス
{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Content-Type": "application/json", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/8.7.1", 
    "X-Amzn-Trace-Id": "Root=1-67c94239-6725112e266c77be1904a9f8"
  }, 
  "origin": "***.***.***.***", 
  "url": "https://httpbin.org/get"
}

-d:データの送信

POST

curl -X POST \
> -H "content-type: application/json" \
> -d '{"first_name":"Tarou","last_name":"Yamada","age":"20"}' \
> 'https://httpbin.org/post'

ver7.82.0以降なら以下のように--json-H-dを使用せずにjsonデータを送信できるようです。-Xもいらないのでかなりスッキリして見やすいです。
今回は昔からある上記のコマンドで試していきます。

curl --json '{"first_name":"Tarou","last_name":"Yamada","age":"20"}' \
> 'https://httpbin.org/post'

レスポンス
{
  "args": {}, 
  "data": "{\"first_name\":\"Tarou\",\"last_name\":\"Yamada\",\"age\":\"20\"}", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Content-Length": "54", 
    "Content-Type": "application/json", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/8.7.1", 
    "X-Amzn-Trace-Id": "Root=1-67c944bc-33471697605a48e957157a5c"
  }, 
  "json": {
    "age": "20", 
    "first_name": "Tarou", 
    "last_name": "Yamada"
  }, 
  "origin": "***.***.***.***", 
  "url": "https://httpbin.org/post"
}

-I:レスポンスヘッダーのみを出力

GET

curl -I 'https://httpbin.org/get'
レスポンス
HTTP/2 200 
date: Thu, 06 Mar 2025 06:48:50 GMT
content-type: application/json
content-length: 254
server: gunicorn/19.9.0
access-control-allow-origin: *
access-control-allow-credentials: true

POST

curl -X POST -I 'https://httpbin.org/post' 
レスポンス
HTTP/2 200 
date: Thu, 06 Mar 2025 06:51:45 GMT
content-type: application/json
content-length: 318
server: gunicorn/19.9.0
access-control-allow-origin: *
access-control-allow-credentials: true

-i:レスポンスヘッダー・ボディーを出力

GET

curl -i 'https://httpbin.org/get'
レスポンス
HTTP/2 200 
date: Thu, 06 Mar 2025 06:53:35 GMT
content-type: application/json
content-length: 254
server: gunicorn/19.9.0
access-control-allow-origin: *
access-control-allow-credentials: true

{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/8.7.1", 
    "X-Amzn-Trace-Id": "Root=1-67c9466f-1a0dd9443a036c5e472e9fbe"
  }, 
  "origin": "***.***.***.***", 
  "url": "https://httpbin.org/get"
}

POST

curl -X POST \
> -H "content-type: application.json" \
> -d '{"first_name":"Tarou","last_name":"Yamada","age":"20"}' \
> -i 'https://httpbin.org/post' 
レスポンス
HTTP/2 200 
date: Thu, 06 Mar 2025 07:10:58 GMT
content-type: application/json
content-length: 527
server: gunicorn/19.9.0
access-control-allow-origin: *
access-control-allow-credentials: true

{
  "args": {}, 
  "data": "{\"first_name\":\"Tarou\",\"last_name\":\"Yamada\",\"age\":\"20\"}", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Content-Length": "54", 
    "Content-Type": "application.json", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/8.7.1", 
    "X-Amzn-Trace-Id": "Root=1-67c94a82-42f3c8850c0b5edb7ce8a7b3"
  }, 
  "json": {
    "age": "20", 
    "first_name": "Tarou", 
    "last_name": "Yamada"
  }, 
  "origin": "***.***.***.***", 
  "url": "https://httpbin.org/post"
}

-v:HTTP通信の詳細を出力

GET

curl -v 'https://httpbin.org/get'
レスポンス
* Host httpbin.org:443 was resolved.
* IPv6: (none)
* IPv4: 44.205.219.248, 44.196.147.43, 54.144.47.213, 34.205.201.49
*   Trying 44.205.219.248:443...
* Connected to httpbin.org (44.205.219.248) port 443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256 / [blank] / UNDEF
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=httpbin.org
*  start date: Aug 20 00:00:00 2024 GMT
*  expire date: Sep 17 23:59:59 2025 GMT
*  subjectAltName: host "httpbin.org" matched cert's "httpbin.org"
*  issuer: C=US; O=Amazon; CN=Amazon RSA 2048 M02
*  SSL certificate verify ok.
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://httpbin.org/get
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: httpbin.org]
* [HTTP/2] [1] [:path: /get]
* [HTTP/2] [1] [user-agent: curl/8.7.1]
* [HTTP/2] [1] [accept: */*]
> GET /get HTTP/2
> Host: httpbin.org
> User-Agent: curl/8.7.1
> Accept: */*
> 
* Request completely sent off
< HTTP/2 200 
< date: Thu, 06 Mar 2025 07:14:09 GMT
< content-type: application/json
< content-length: 254
< server: gunicorn/19.9.0
< access-control-allow-origin: *
< access-control-allow-credentials: true
< 
{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/8.7.1", 
    "X-Amzn-Trace-Id": "Root=1-67c94b41-65631b3f2d6d993c00a431bc"
  }, 
  "origin": "***.***.***.***", 
  "url": "https://httpbin.org/get"
}

POST

curl -X POST \                   
-H "content-type: application.json" \
-d '{"first_name":"Tarou","last_name":"Yamada","age":"20"}' \
-v 'https://httpbin.org/post'
レスポンス
* Host httpbin.org:443 was resolved.
* IPv6: (none)
* IPv4: 44.205.219.248, 54.144.47.213, 34.205.201.49, 44.196.147.43
*   Trying 44.205.219.248:443...
* Connected to httpbin.org (44.205.219.248) port 443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256 / [blank] / UNDEF
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=httpbin.org
*  start date: Aug 20 00:00:00 2024 GMT
*  expire date: Sep 17 23:59:59 2025 GMT
*  subjectAltName: host "httpbin.org" matched cert's "httpbin.org"
*  issuer: C=US; O=Amazon; CN=Amazon RSA 2048 M02
*  SSL certificate verify ok.
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://httpbin.org/post
* [HTTP/2] [1] [:method: POST]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: httpbin.org]
* [HTTP/2] [1] [:path: /post]
* [HTTP/2] [1] [user-agent: curl/8.7.1]
* [HTTP/2] [1] [accept: */*]
* [HTTP/2] [1] [content-type: application.json]
* [HTTP/2] [1] [content-length: 54]
> POST /post HTTP/2
> Host: httpbin.org
> User-Agent: curl/8.7.1
> Accept: */*
> content-type: application.json
> Content-Length: 54
> 
* upload completely sent off: 54 bytes
< HTTP/2 200 
< date: Thu, 06 Mar 2025 07:17:56 GMT
< content-type: application/json
< content-length: 527
< server: gunicorn/19.9.0
< access-control-allow-origin: *
< access-control-allow-credentials: true
< 
{
  "args": {}, 
  "data": "{\"first_name\":\"Tarou\",\"last_name\":\"Yamada\",\"age\":\"20\"}", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Content-Length": "54", 
    "Content-Type": "application.json", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/8.7.1", 
    "X-Amzn-Trace-Id": "Root=1-67c94c23-11076a6c5a5dea02243fce96"
  }, 
  "json": {
    "age": "20", 
    "first_name": "Tarou", 
    "last_name": "Yamada"
  }, 
  "origin": "***.***.***.***", 
  "url": "https://httpbin.org/post"
}

-o:指定したファイルに出力

GET

curl -o curltest.txt 'https://httpbin.org/get'
レスポンス
cat curltest.txt # ファイル確認
{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/8.7.1", 
    "X-Amzn-Trace-Id": "Root=1-67c94fd3-0fe7cd3e1eb8b21b7342af3a"
  }, 
  "origin": "***.***.***.***", 
  "url": "https://httpbin.org/get"
}

POST

curl -X POST \                   
-H "content-type: application.json" \
-d '{"first_name":"Tarou","last_name":"Yamada","age":"20"}' \
-o curl_post_test.txt 'https://httpbin.org/post'
レスポンス
cat curl_post_test.txt # ファイル確認
{
  "args": {}, 
  "data": "{\"first_name\":\"Tarou\",\"last_name\":\"Yamada\",\"age\":\"20\"}", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "application/json", 
    "Content-Length": "54", 
    "Content-Type": "application/json", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/8.7.1", 
    "X-Amzn-Trace-Id": "Root=1-67c95240-33b6eb2f1fe2ad677c58d801"
  }, 
  "json": {
    "age": "20", 
    "first_name": "Tarou", 
    "last_name": "Yamada"
  }, 
  "origin": "***.***.***.***", 
  "url": "https://httpbin.org/post"
}

-O:リクエスト先の名前のファイルに出力

curl -O 'https://httpbin.org/get'
レスポンス
cat get # ファイル確認
{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/8.7.1", 
    "X-Amzn-Trace-Id": "Root=1-67c950b7-2631a9ab63e41c67359a222f"
  }, 
  "origin": "***.***.***.***", 
  "url": "https://httpbin.org/get"
}

POST

curl -X POST \                   
-H "content-type: application.json" \
-d '{"first_name":"Tarou","last_name":"Yamada","age":"20"}' \
-O 'https://httpbin.org/post'
レスポンス
cat post # ファイル確認
{
  "args": {}, 
  "data": "{\"first_name\":\"Tarou\",\"last_name\":\"Yamada\",\"age\":\"20\"}", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "application/json", 
    "Content-Length": "54", 
    "Content-Type": "application/json", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/8.7.1", 
    "X-Amzn-Trace-Id": "Root=1-67c95344-62b75b132391d41b78563221"
  }, 
  "json": {
    "age": "20", 
    "first_name": "Tarou", 
    "last_name": "Yamada"
  }, 
  "origin": "***.***.***.***", 
  "url": "https://httpbin.org/post"
}

-s:進行状況・エラー・警告を非表示

GET

# 間違ったURL
curl -s 'https://httpbin/get';  
レスポンス
# レスポンス
# 出力は空になる。

POST

# 間違ったURL
curl -X POST \                   
-H "content-type: application.json" \
-d '{"first_name":"Tarou","last_name":"Yamada","age":"20"}' \
-s 'https://httpbin/post'
レスポンス
# レスポンス
# 出力は空になる。

-f:400以上のレスポンスコードを返す

curlでは400以上のエラーが返されても表示してくれません。
-fオプションを使用すれば、表示されます。

GET

curl -f 'https://httpbin.org/status/404'
レスポンス
curl: (56) The requested URL returned error: 404

POST

curl -X POST \                   
-H "content-type: application.json" \
-d '{"first_name":"Tarou","last_name":"Yamada","age":"20"}' \
-f 'https://httpbin.org/status/505'
レスポンス
curl: (56) The requested URL returned error: 505

おわりに

実際にコマンドを叩いてみると、どんなデータがリクエストとして送られ、レスポンスとして返ってくるのかわかりやすかったです。
curlには今回紹介したオプション以外にも、大量のオプションが存在しています。
今後の業務では認証周りを触ることになりそうなので、そのあたりのコマンドも学習していこうと思います。

参考資料

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?