curlはデフォルトでレスポンスボディを標準出力に表示する。ステータスコードと所要時間だけ知りたい場合、ボディの表示は不要である。-o /dev/nullでボディを破棄し、-wオプションで必要な値だけを出力する。

curlはデフォルトでレスポンスボディを表示する

curlにURLを指定すると、レスポンスボディがそのまま標準出力に表示される。

$ curl https://example.com
<!doctype html>
<html>
<head>
    <title>Example Domain</title>
...

ステータスコードや処理時間の確認だけが目的の場合、このボディ表示は邪魔になる。

-o /dev/nullでレスポンスボディを破棄する

-oオプションでレスポンスの出力先を/dev/nullに指定すると、ボディを画面に表示せず破棄できる。

$ curl -o /dev/null https://example.com
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   559  100   559    0     0  10445      0 --:--:-- --:--:-- --:--:--     0

ボディの表示は消えたが、代わりに進捗メーターが表示される。

-sで進捗メーターを消す

-s(--silent)オプションを付けると、進捗メーターも表示されなくなる。

$ curl -o /dev/null -s https://example.com
$

何も出力されない状態になった。ここに-wオプションで必要な情報を追加する。

-wでステータスコードと所要時間を出力する

-w(--write-out)オプションは、レスポンス受信後に指定したフォーマットで情報を出力する。ステータスコードは%{http_code}、所要時間は%{time_total}で取得できる。

$ curl -o /dev/null -s -w "%{http_code} %{time_total}\n" https://example.com
200 0.070141

ステータスコード200と、所要時間0.070141秒だけが出力された。フォーマット末尾の\nは改行がないとプロンプトと出力が同じ行に並んでしまうため付けている。

404など異常系でも同様にステータスコードと所要時間を取得できる。

$ curl -o /dev/null -s -w "%{http_code} %{time_total}\n" https://example.com/notfound
404 0.050714

-f(--fail)オプションを付けていないため、404の場合もcurlコマンド自体の終了ステータスは0になる。終了ステータスで成否を判定したい場合は【curl】404 Not Foundで0以外の終了ステータスコードを返すようにする を参照。

-wで取得できる主な値

%{http_code}%{time_total}以外にも、-wではさまざまな値を取得できる。

変数内容
%{http_code}HTTPステータスコード
%{time_total}リクエスト開始からレスポンス完了までの合計時間(秒)
%{time_connect}TCP接続確立までの時間(秒)
%{time_starttransfer}レスポンスの最初のバイトを受信するまでの時間(秒)
%{size_download}ダウンロードしたバイト数
%{url_effective}リダイレクト後の最終的なURL

複数の値をまとめて出力する場合は次のように書く。

$ curl -o /dev/null -s -w "status=%{http_code} total=%{time_total} connect=%{time_connect} starttransfer=%{time_starttransfer}\n" https://example.com
status=200 total=0.053096 connect=0.015595 starttransfer=0.053039

time_totaltime_starttransferの差が小さいほど、TTFB(Time To First Byte)以降のボディ転送にかかる時間が短いと分かる。

ヘルスチェックスクリプトへの応用

シェルスクリプトでステータスコードと所要時間を変数に取り込み、条件分岐に使う例。

#!/bin/bash

RESULT=$(curl -o /dev/null -s -w "%{http_code} %{time_total}" https://example.com)
STATUS_CODE=$(echo "$RESULT" | cut -d ' ' -f 1)
TIME_TOTAL=$(echo "$RESULT" | cut -d ' ' -f 2)

if [ "$STATUS_CODE" != "200" ]; then
  echo "NG: status=$STATUS_CODE"
  exit 1
fi

echo "OK: status=$STATUS_CODE time=${TIME_TOTAL}s"

レスポンスボディを読み込まずに済むため、ヘルスチェックや死活監視の定期実行に組み込んでも負荷が小さい。

参考