HTTPステータスコードが200でない場合、0以外のexitCodeでcURLを失敗させることはできますか?


239

curlがHTTP 500応答を受け取ったとき、失敗を意味する終了コード(!= 0)を返すといつも思っていましたが、そうではないようです。

HTTPステータスコードが200でない場合、cURLを0以外のexitCodeで失敗させる方法はありますか?私は使用できることを知っています-w "%{http_code}"が、それは終了コードとしてではなくSTDOUTに入れます(また、ファイルにリダイレクトしたくないが、画面に出力したい出力をキャプチャすることに興味があります)。

回答:


264

curl --fail あなたが望むものの一部をします:

からman curl

-f, --fail

(HTTP)サーバーエラーでサイレントに失敗します(まったく出力されません)。これは主に、スクリプトなどを有効にして失敗した試行をよりうまく処理するために行われます。通常、HTTPサーバーがドキュメントの配信に失敗すると、その旨を記載したHTMLドキュメントが返されます(多くの場合、理由も説明されています)。このフラグは、curlがそれを出力するのを防ぎ、エラー22を返します。

この方法はフェイルセーフではありません。特に認証が関係している場合(応答コード401および407)、失敗した応答コードがすり抜ける場合があります。

ただし、画面への出力はブロックされます。


2
それで、それのどの部分がするのかしないのですか?
rogerdpack

5
@rogerdpack tl; dr不正な応答を検出するとゼロ以外を返しますが、OPに応答をキャプチャさせません
ランプオン

3
これはHTTP 301 Move Permanentlyをキャッチしません。カールはまだ終了コード0を与えました。
wisbucky18年

4
@wisbucky 301はエラーではなく、リダイレクトステータスコードです。エラーは4xxおよび5xxステータスコードです。
M.ジャスティン

1
@wisbuckyは、HTTPエラーコードでゼロ以外を終了し HTTPリダイレクトを正しく処理するためにcurl -f -Lこの質問を参照してください-L
ノア・サスマン

81

カールしたページのコンテンツを表示するだけの場合は、次の操作を実行できます。

STATUSCODE=$(curl --silent --output /dev/stderr --write-out "%{http_code}" URL)

if test $STATUSCODE -ne 200; then
    # error handling
fi

これにより、ページのコンテンツがSTDERRに書き込まれ、HTTPステータスコードがSTDOUTに書き込まれるため、変数STATUSCODEに割り当てることができます。


3
失敗時に応答(200以外)を出力したいが0、スクリプトから非ステータスコードを返す場合はどうでしょうか。
ジャスティン

2
@ジャスティン:どうif [ "$statuscode" -ne 200 ]; then exit "$statuscode"; fi
ゴティ

4
@ghoti:署名されていない8ビットの終了コードのみがサポートされているため、少し混乱する可能性があります。
デニス

3
ああ、正しい-そしてコードは8ビットで折り返されるので、エラー404は終了値148になり、500は244になります。:-)
ゴティ

7
わずかなバリエーションとして、これは、stderrではなくstdoutに応答をリダイレクトするときに変数にコードをキャプチャします{ code=$(curl ... as above ...); } 2>&1。トリックは{ ... } 2>&1、異なるシェルを生成することなくリダイレ​​クトを許可する( ... )ことです。
トビア

31

フラグの組み合わせを使用してそれを行うことができました:

curl --silent --show-error --fail URL

--silentは進行状況とエラーを隠します
--show-error--silent
--failによって隠されたエラーメッセージを表示しますリクエストが失敗すると終了コード> 0を返します


5
これはサーバーの応答を表示しません。私はOPではありませんが、私は彼がサーバーから返されたエラーメッセージを本文で見たかったのではないかと疑っています。だけでなく、--silent --show-error --fail同じように動作し-f/--failます。
廃棄物

1
実際に--fail22文書化されているように終了コードを返します。
クオロネルの質問

2
@wisbucky 301はエラーではなく、リダイレクトステータスコードです。エラーは4xxおよび5xxステータスコードです。
M.ジャスティン

4
@wisbuckyに公平を期すために、元の質問には「[...] HTTPステータスコードが200でない場合」と記載されています。以前は「エラー」について言及していません。
ケン

2
@ M.Justin curl manページによると:この方法はフェイルセーフではなく、特に認証が関係する場合(応答コード401および407)、失敗した応答コードがすり抜ける場合があります。
youfu

0

はい、それを行う方法はありますが、3つのカールオプションが含まれているため、明らかではありません。

curl -s --fail --show-error https://httpbin.org/status/200 > /dev/null
curl -s --fail --show-error https://httpbin.org/status/401 > /dev/null
curl -s --fail --show-error https://httpbin.org/status/404 > /dev/null
curl -s --fail --show-error https://bleah-some-wrong-host > /dev/null

これにより、curlが最終2xxリターンコードで終了しstdout、本体を取得したときにのみ成功(0)が発生し、エラーがstderrに表示されることが保証されます。

curlのドキュメントでは、401コードの一部で--failが成功する可能性があることに言及しているため、少し混乱する可能性があることに注意してください。少なくとも--show-errorと同時に使用した場合は、正しくないテストに基づきます。

これまでのところ、これらのオプションでhttp-succedsでなかったときにcurlが成功を返すケースを見つけることができませんでした。


1
これは、リカルド・スーザのものと本質的に同じ答えですか?
knocte
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.