Mendapatkan ikal untuk mengeluarkan kode status HTTP?

799

Saya menggunakan curldi baris perintah di Linux untuk mengeluarkan permintaan HTTP. Badan respons dicetak dengan standar keluar, yang baik-baik saja, tetapi saya tidak dapat melihat dari halaman manual cara mendapatkan ikal untuk mencetak kode status HTTP dari respons (404, 403 dll). Apakah ini mungkin?

kdt
sumber
Sedangkan saya, saya bisa melihat dari manual cara mendapatkan kode status HTTP, tetapi opsi -w tidak berfungsi. Saya telah melaporkan bug ke Apple.
Nicolas Barbulesco
19
The -ibendera, seperti dalam curl -i https://www.example.com/, mungkin apa yang Anda inginkan, sesuai superuser.com/a/514798/190188
gak
Kenapa tidak seperti itu saja curl -IL http://www.example.com | grep "^HTTP\/"?
St3an
Tidak untuk masa depan: jawaban yang Anda inginkan mungkin adalah milik Cyril David (saat ini di posisi 4)
WhiteHotLoveTiger

Jawaban:

525

Ini akan berfungsi untuk Anda jika server web dapat menanggapi permintaan HEAD (ini tidak akan melakukan a GET):

curl -I http://www.example.org

Sebagai tambahan, untuk membiarkan CURL mengikuti arahan ulang (3xx status) tambahkan -L.

pberlijn
sumber
155
NB: curl -Imelakukan permintaan HTTP HEAD, yang dapat bermasalah untuk menguji kode status HTTP untuk beberapa server dan layanan aplikasi web
Jay Taylor
16
Dan untuk mendapatkan nomor status saja, kirimkan kehead -n 1|cut -d$' ' -f2
Benubird
33
Jangan lupa untuk mengarahkan stderr ikal ini: curl -I http://www.example.org 2>/dev/null | head -n 1 | cut -d$' ' -f2. Tambahkan -L ke ikal jika Anda membutuhkan status akhir setelah pengalihan.
Aaron Blenkush
1
Mengikuti pengalihan setelah hanya melakukan permintaan HEAD dapat menyebabkan perilaku menarik, tergantung pada bagaimana aplikasi diprogram.
Scott McIntyre
31
curl -I -X GETakan mengirim permintaan GET, tetapi memberikan hasil yang sama.
jiggy
835

Cara yang lebih spesifik untuk mencetak hanya kode status HTTP adalah sesuatu di sepanjang baris:

curl -s -o /dev/null -w "%{http_code}" http://www.example.org/

Jauh lebih mudah untuk dikerjakan dalam skrip, karena tidak memerlukan parsing :-)

Parameter -Imungkin ditambahkan untuk meningkatkan kinerja beban respons. Parameter ini hanya meminta status / header tanggapan, tanpa badan tanggapan unduhan.

Catatan: %{http_code} kembali pada baris pertama payload HTTP

yaitu:

curl -s -o /dev/null -I -w "%{http_code}" http://www.example.org/
pvandenberk
sumber
54
-w "% {http_code}" adalah bit yang mencetak kode status. Anda dapat menambahkan satu atau dua baris baru di sana untuk memisahkan kode dari badan (-w "\ n \ n% {http_code} \ n")
Jeffrey Martinez
7
Wow, ini /dev/nullbahkan berfungsi di Windows curl versi yang saya gunakan.
Uwe Keim
3
Saya percaya ini mengunduh seluruh file meskipun semuanya ke / dev / null, jadi tidak ideal untuk memeriksa kode status untuk file besar. httping -c 1 -s -G -mmengeluarkan GET dan tidak mengunduh keseluruhan file, meskipun saya menyadari pertanyaan ini khusus tentang curl.
RomanSt
40
FYI: -s= Jangan tampilkan kemajuan unduhan, -o /dev/null= jangan tampilkan isi, -w "%{http_code}"= Tulis kode respons http ke stdout setelah keluar.
Ajedi32
1
Apakah kutipan di sekitar "% {http_code}" diperlukan?
Hakan Baba
217

Jika Anda ingin melihat tajuk serta hasilnya, Anda dapat menggunakan opsi verbose:

curl -v http://www.example.org
curl --verbose http://www.example.org

Status akan muncul di tajuk. Misalnya

< Date: Tue, 04 Nov 2014 19:12:59 GMT
< Content-Type: application/json; charset=utf-8
< Status: 422 Unprocessable Entity
Enrico Susatyo
sumber
26
+1 untuk menunjukkan bendera verbose memberikan detail tambahan. Bagus untuk menguji aplikasi REST.
MrOodles
8
+1 sangat mudah digunakan ketika melakukan permintaan POST (curl -v --data "...")
MegaTux
1
Bahkan membagi mereka dalam dua output file yang berbeda (detail status http ke stderr dan respon body to stdout)
phil294
201

Anda dapat mencetak kode status, selain semua tajuk dengan melakukan hal berikut:

curl -i http://example.org

Hal yang baik tentang -iitu bekerja dengan -X POSTbaik.

Cyril David
sumber
36
Jauh lebih baik daripada jawaban yang diterima (yang melakukan permintaan KEPALA).
neu242
10
Mungkin jelas, tetapi -ibekerja dengan metode HTTP apa pun , bukan hanya GETdan POST... :)
mac
3
jawaban terbaik karena membuat keluaran keriting baik tajuk maupun badan, membuatnya cocok untuk sebagian besar tugas saat digunakan dalam skrip
Sarge Borsch
6
Ini adalah jawaban terbaik, dan dapat digunakan bersama dengan -s(jangan tampilkan progress meter atau pesan kesalahan) dan -S(jangan tampilkan pesan kesalahan)
Jonathan Hartley
69

Jika Anda ingin mengambil kode status HTTP dalam suatu variabel, tetapi masih mengarahkan konten ke STDOUT, Anda harus membuat dua STDOUT. Anda dapat melakukannya dengan subtitusi proses> () dan memerintahkan subtitusi $ () .

Pertama, buat deskriptor file 3untuk proses STDOUT Anda saat ini dengan exec 3>&1.

Kemudian, gunakan -oopsi curl untuk mengarahkan ulang konten respons ke fifo sementara menggunakan substitusi perintah, dan kemudian di dalam substitusi perintah itu, redirect output kembali ke proses Anda saat ini STDOUT 3dengan deskriptor file -o >(cat >&3).

Menyatukan semuanya dalam bash 3.2.57(1)-release(standar untuk macOS):

# creates a new file descriptor 3 that redirects to 1 (STDOUT)
exec 3>&1 
# Run curl in a separate command, capturing output of -w "%{http_code}" into HTTP_STATUS
# and sending the content to this command's STDOUT with -o >(cat >&3)
HTTP_STATUS=$(curl -w "%{http_code}" -o >(cat >&3) 'http://example.com')

Perhatikan bahwa ini tidak berfungsi /bin/shseperti yang dicatat oleh SamK dalam komentar di bawah .

Perbatasan Heath
sumber
5
Itu jas hujan yang serius ... dan saya menyukainya!
spyle
3
Sekarang bagaimana, pada gilirannya, dapatkah saya mengarahkan output ke variabel lain?
Roger Filmyer
1
Keluaran dalam STDOUT, jadi Anda harus dapat mengarahkan keluaran dari perintah ke mana pun Anda suka seperti perintah biasa. Saya belum menguji ini.
Perbatasan Heath
1
Tidak bekerja dengan / bin / sh.
SamK
jawaban yang bagus, Anda juga dapat mengarahkan ulang ke file nyata dan menyimpannya nanti jika Anda menginginkan portabilitas shell
akostadinov
32

Definisikan kembali curl output:

curl -sw '%{http_code}' http://example.org

Dapat digunakan dengan jenis permintaan apa pun.

Grzegorz Luczywo
sumber
-k (--insecure) menimpa -s (diam).
Ravichandra
16

Kode status HANYA

[0]$ curl -LI http://www.example.org -o /dev/null -w '%{http_code}\n' -s
[0]$ 200

Semua kredit untuk GIST ini

mahatmanich
sumber
11

Ini adalah curl --failbatasan yang menyakitkan . Dari man curl:

-f, --fail (HTTP) Gagal diam-diam (tidak ada output sama sekali) pada kesalahan server

Tetapi tidak ada cara untuk mendapatkan kode pengembalian non-nol DAN badan respons di stdout.

Berdasarkan jawaban pvandenberk dan trik lain yang sangat berguna yang dipelajari pada SO , berikut ini solusinya:

curl_with_error_code () {
    _curl_with_error_code "$@" | sed '$d'
}
_curl_with_error_code () {
    local curl_error_code http_code
    exec 17>&1
    http_code=$(curl --write-out '\n%{http_code}\n' "$@" | tee /dev/fd/17 | tail -n 1)
    curl_error_code=$?
    exec 17>&-
    if [ $curl_error_code -ne 0 ]; then
        return $curl_error_code
    fi
    if [ $http_code -ge 400 ] && [ $http_code -lt 600 ]; then
        echo "HTTP $http_code" >&2
        return 127
    fi
}

Fungsi ini berperilaku persis seperti curl, tetapi akan mengembalikan 127 (kode pengembalian tidak digunakan oleh curl) dalam kasus kode HTTP dalam kisaran [400, 600 [.

Lucas Cimon
sumber
Setuju, tidak bisa melihat output kesalahan adalah batasan yang menyakitkan dari kegagalan - sangat berguna. Bagaimana Anda bisa mendiagnosis kegagalan api REST tanpa melihat output kesalahan? Sangat disayangkan bahwa pemilik curl bagder dengan keras kepala bersikeras untuk tidak memberikan --fail-but-show-error. github.com/curl/curl/issues/1978
jamshid
Sebagaimana dinyatakan dalam dokumentasi, itu tidak berfungsi untuk 401 dan 407 kode HTTP :(
Logan Mzz
11

Ini akan mengirimkan permintaan ke url, dapatkan hanya baris pertama dari respons, pisahkan pada blok dan pilih yang kedua.

Ini berisi kode respons

curl -I http://example.org 2>/dev/null | head -n 1 | cut -d$' ' -f2
Filip Spiridonov
sumber
1
Bisakah Anda menjelaskan apa yang kode ini lakukan dan bagaimana mengatasi masalah yang diberikan oleh OP? Kode yang tidak dapat dijelaskan dapat tampak tidak dipercaya dan berbahaya bagi pengguna.
bwDraco
1
Tentu, kami mengirim permintaan ke url, hanya mendapatkan baris pertama dari respons, membaginya menjadi beberapa blok dan memilih yang kedua. Ini berisi kode respons yang dicari OP.
Filip Spiridonov
9

Untuk permintaan POST, yang berikut ini berfungsi:

curl -w 'RESP_CODE:%{response_code}' -s -X POST --data '{"asda":"asd"}' http://example.com --header "Content-Type:application/json"|grep -o  'RESP_CODE:[1-4][0-9][0-9]'
zafar142003
sumber
6

Gunakan perintah CURL berikut dan pipa untuk grep seperti:

$ curl -I -s -L http://example.com/v3/get_list | grep "HTTP / 1.1"

Inilah yang dilakukan oleh setiap bendera:

  • -I: Tampilkan hanya header tanggapan
  • -s: Diam - Jangan tampilkan bilah kemajuan
  • -L: Ikuti Location:tajuk

Berikut ini tautan ke kode status HTTP .

Jalankan dari baris perintah. Ikal ini berjalan dalam mode diam, mengikuti arahan ulang, dapatkan header HTTP. grep akan mencetak kode status HTTP ke output standar.

Savitoj Singh
sumber
5
curl -so -i /dev/null -w "%{http_code}"  http://www.any_example.com

Ini akan mengembalikan informasi berikut:

  1. data respons, jika ada data yang dikembalikan oleh API seperti kesalahan
  2. Kode status
srana
sumber
Ini tidak mengikuti arahan ulang. Jawaban yang ada ini lebih baik superuser.com/a/442395/475508
cricket_007
Tentu, Anda bisa merujuk itu juga !!
srana
4

Berikut adalah beberapa perintah curl yang menggunakan GETdan yang mengembalikan kode HTTP.

curl -so /dev/null -w '%{response_code}' http://www.example.org

Harap diingat bahwa pendekatan di bawah ini menggunakan HEAD, yang lebih cepat tetapi mungkin tidak berfungsi dengan baik dengan beberapa server HTTP yang kurang patuh web.

 curl -I http://www.example.org
Sorin
sumber
Setidaknya tidak bekerja pada OS X.
Ain
Bekerja dengan baik untuk saya di OS X High Sierra 10.13.6.
Ben Baron
4

Contoh cara menggunakan kode respons. Saya menggunakan ini untuk mengunduh ulang basis data Geolite hanya jika mereka telah mengubah ( -z) & juga mengikuti arahan ulang ( -L):

url=http://example.com/file.gz
file=$(basename $url)

response=$(curl -L -s -o $file -z $file $url -w "%{http_code}")

case "$response" in
        200) do_something ;;
        301) do_something ;;
        304) printf "Received: HTTP $response (file unchanged) ==> $url\n" ;;
        404) printf "Received: HTTP $response (file not found) ==> $url\n" ;;
          *) printf "Received: HTTP $response ==> $url\n" ;;
esac
Stuart Cardall
sumber
3

OP ingin mengetahui kode status. Seringkali saat mengunduh file Anda juga ingin merasakan ukurannya jadi saya menggunakan curl terlebih dahulu untuk menunjukkan kode status dan ukuran file dan kemudian matikan verbose dan arahkan file ke tempat dan nama yang saya inginkan:

curl -R -s -S -w  "\nhttp: %{http_code} %{size_download}\n" -o /Users/myfiles/the_local_name.html http://archive.onweb.com/the_online_name.html

Lalu saya menunggu finishing dari curl

wait ${!}

sebelum saya menjalankan perintah selanjutnya. Di atas ketika digunakan dalam skrip banyak perintah seperti di atas memberikan respons yang bagus seperti:

http: 200 42824

http: 200 34728

http: 200 35452

Harap dicatat bahwa -o dalam curl harus diikuti oleh path lengkap file + nama file. Ini memungkinkan Anda untuk menyimpan file dalam struktur nama yang masuk akal ketika Anda menggunakan file tersebut dengan ikal. Perhatikan juga bahwa -s dan -S yang digunakan bersama-sama membungkam output tetapi tidak menunjukkan kesalahan. Perhatikan juga bahwa -R mencoba mengatur stempel waktu file ke file web.

Jawaban saya didasarkan pada apa yang semula disarankan @pvandenberk, tetapi selain itu sebenarnya menyimpan file di suatu tempat, alih-alih hanya mengarahkan ke / dev / null.

sakumatto
sumber
1

Pisahkan konten output menjadi stdoutdan kode status HTTP ke stderr:

curl http://www.example.org -o >(cat >&1) -w "%{http_code}\n" 1>&2

Jika hanya kode status HTTP yang diinginkan untuk stderr, --silentdapat digunakan:

curl --silent http://www.example.org -o >(cat >&1) -w "%{http_code}\n" 1>&2

Aliran yang diinginkan kemudian dapat dipilih dengan mengarahkan yang tidak diinginkan ke /dev/null:

$ (curl --silent http://www.example.org -o >(cat >&1) -w "%{http_code}" 1>&2) 1>/dev/null
200
$ (curl --silent http://www.example.org -o >(cat >&1) -w "%{http_code}" 1>&2) 2>/dev/null
<!doctype html>
...

Perhatikan bahwa untuk pengalihan kedua agar berperilaku seperti yang diinginkan, kita perlu menjalankan perintah curl dalam subkulit.

Jaakko
sumber
1
Membutuhkan bashproses substitusi.
Jaakko
@ Bruno, saya mengubah contoh dari superuser.com/revisions/1444693/2 , karena saya pikir /tmp/out /tmp/errfile dapat menyebabkan hasil yang tidak terduga jika dijalankan secara paralel.
Jaakko