รับ curl เพื่อส่งออกรหัสสถานะ HTTP?


799

ฉันใช้curlที่บรรทัดคำสั่งบน Linux เพื่อออกคำขอ HTTP ส่วนเนื้อหาการตอบสนองถูกพิมพ์ออกมาเป็นมาตรฐานซึ่งใช้ได้ แต่ฉันไม่สามารถดูได้จากหน้า man วิธีรับ curl เพื่อพิมพ์รหัสสถานะ HTTP จากการตอบกลับ (404, 403 ฯลฯ ) เป็นไปได้ไหม


สำหรับฉันฉันเห็นได้จากคู่มือวิธีรับรหัสสถานะ HTTP แต่ตัวเลือก -w ไม่ทำงาน ฉันได้รายงานข้อบกพร่องของ Apple แล้ว
Nicolas Barbulesco

19
-iธงในขณะที่curl -i https://www.example.com/อาจจะเป็นสิ่งที่คุณต้องการเป็นต่อsuperuser.com/a/514798/190188
กา

ทำไมไม่เป็นเช่นนั้นcurl -IL http://www.example.com | grep "^HTTP\/"?
St3an

ไม่ใช่เพื่อตัวเองในอนาคต: คำตอบที่คุณต้องการน่าจะเป็นของไซริลเดวิด (อยู่ในตำแหน่งที่ 4)
WhiteHotLoveTiger

คำตอบ:


526

สิ่งนี้ควรใช้กับคุณถ้าเว็บเซิร์ฟเวอร์สามารถตอบสนองต่อคำขอ HEAD ได้ (สิ่งนี้จะไม่ทำงานGET):

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

นอกจากนี้เพื่อให้ cURL ติดตามการเปลี่ยนเส้นทาง (สถานะ 3xx) เพิ่ม -L


155
หมายเหตุ: curl -Iไม่ได้ร้องขอ HEAD HTTP ซึ่งอาจเป็นปัญหาสำหรับการทดสอบรหัสสถานะ HTTP สำหรับแอพพลิเคชันเซิร์ฟเวอร์บางเว็บและบริการ
เจย์เทย์เลอร์

16
และเพื่อให้ได้เพียงหมายเลขสถานะให้ส่งไปที่head -n 1|cut -d$' ' -f2
นูร์เดียร์

33
อย่าลืมที่จะเปลี่ยนเส้นทาง stderr curl -I http://www.example.org 2>/dev/null | head -n 1 | cut -d$' ' -f2ขดของ: เพิ่ม -L เพื่อม้วนถ้าคุณต้องการสถานะสุดท้ายหลังจากเปลี่ยนเส้นทาง
Aaron Blenkush

1
การติดตามการเปลี่ยนเส้นทางหลังจากทำตามคำขอ HEAD เท่านั้นอาจทำให้เกิดพฤติกรรมที่น่าสนใจขึ้นอยู่กับการตั้งโปรแกรมของแอพ
Scott McIntyre

31
curl -I -X GETจะส่งคำขอ GET แต่ให้ผลลัพธ์เดียวกัน
jiggy

835

วิธีที่เฉพาะเจาะจงมากขึ้นจะพิมพ์ออกมาเพียงแค่รหัสสถานะ HTTP คือสิ่งที่ตามสายของ:

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

ทำงานกับสคริปต์ได้ง่ายขึ้นมากเนื่องจากไม่ต้องแยกวิเคราะห์ :-)

-Iอาจเพิ่มพารามิเตอร์เพื่อปรับปรุงประสิทธิภาพการตอบสนองการโหลด พารามิเตอร์นี้ร้องขอสถานะ / ส่วนหัวของการตอบกลับโดยไม่ต้องมีเนื้อหาตอบกลับการดาวน์โหลด

หมายเหตุ: %{http_code}ส่งคืนบรรทัดแรกของส่วนของข้อมูล HTTP

เช่น:

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

54
-w "% {http_code}" เป็นบิตที่พิมพ์รหัสสถานะ คุณสามารถเพิ่มบรรทัดใหม่หรือสองบรรทัดเพื่อแยกรหัสออกจากเนื้อความ (-w "\ n \ n% {http_code} \ n")
เจฟฟรีย์มาร์ติเนซ

7
ว้าว/dev/nullสิ่งนี้ใช้ได้กับ curl รุ่น Windows ที่ฉันใช้อยู่
Uwe Keim

3
ฉันเชื่อว่าสิ่งนี้จะดาวน์โหลดไฟล์ทั้งหมดแม้ว่าจะไปที่ / dev / null ดังนั้นจึงไม่เหมาะสำหรับการตรวจสอบรหัสสถานะสำหรับไฟล์ขนาดใหญ่ httping -c 1 -s -G -mออก GET และไม่ดาวน์โหลดไฟล์ทั้งหมดถึงแม้ว่าฉันจะรู้ว่าคำถามนี้เกี่ยวกับ curl โดยเฉพาะ
RomanSt

40
FYI: -s= ไม่แสดงความคืบหน้าในการดาวน์โหลด-o /dev/null= ไม่แสดงเนื้อหา-w "%{http_code}"= เขียนรหัสตอบกลับ http ไปยัง stdout หลังจากออก
Ajedi32

1
จำเป็นต้องใช้เครื่องหมายคำพูดรอบ "% {http_code}" หรือไม่
Hakan Baba

216

หากคุณต้องการเห็นส่วนหัวและผลลัพธ์คุณสามารถใช้ตัวเลือก verbose:

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

สถานะจะปรากฏในส่วนหัว เช่น

< Date: Tue, 04 Nov 2014 19:12:59 GMT
< Content-Type: application/json; charset=utf-8
< Status: 422 Unprocessable Entity

26
+1 สำหรับการชี้ให้เห็นธง verbose ให้รายละเอียดเพิ่มเติม เหมาะสำหรับการทดสอบแอป REST
MrOodles

8
+1 ใช้งานง่ายมากเมื่อทำคำขอ POST (curl -v --data "... ")
MegaTux

1
มันยังแยกพวกเขาในสองออกไฟล์ที่แตกต่างกัน (รายละเอียดสถานะ http เพื่อ stderr และตอบสนองของร่างกายที่ stdout)
Blauhirn

201

คุณสามารถพิมพ์รหัสสถานะได้นอกเหนือจากส่วนหัวทั้งหมดโดยทำดังต่อไปนี้:

curl -i http://example.org

ข้อดีของ-iมันก็คือมันทำงานได้-X POSTดีเช่นกัน


36
ดีกว่าคำตอบที่ได้รับการยอมรับดีกว่า
neu242

10
อาจจะชัดเจน แต่-iทำงานกับวิธี HTTP ใด ๆไม่ใช่แค่GETและPOST... :)
mac

3
คำตอบที่ดีที่สุดเนื่องจากทำให้ส่วนหัวและเนื้อหาของม้วนงอทำให้เหมาะสำหรับงานส่วนใหญ่เมื่อใช้ในสคริปต์
Sarge Borsch

6
นี่เป็นคำตอบที่ดีที่สุดและสามารถใช้ร่วมกับ-s(ไม่แสดงตัววัดความคืบหน้าหรือข้อความ-Sแสดงข้อผิดพลาด) และ(อย่าแสดงข้อความแสดงข้อผิดพลาด)
Jonathan Hartley

69

หากคุณต้องการจับรหัสสถานะ HTTP ในตัวแปร แต่ยังคงเปลี่ยนเส้นทางเนื้อหาไปยัง STDOUT คุณต้องสร้าง STDOUT สองรายการ คุณสามารถทำได้ด้วยขั้นตอนการเปลี่ยนตัว> ()และคำสั่งเปลี่ยนตัว $ ()

ขั้นแรกให้สร้างบ่งแฟ้ม3สำหรับกระบวนการปัจจุบันของคุณ STDOUT exec 3>&1กับ

จากนั้นใช้ขดของ-oตัวเลือกในการเปลี่ยนเส้นทางเนื้อหาการตอบสนองไปยัง FIFO ชั่วคราวโดยใช้แทนคำสั่งแล้วภายในแทนคำสั่งที่เปลี่ยนเส้นทางออกกลับไปให้คำอธิบายถึงกระบวนการ STDOUT ไฟล์ปัจจุบันของคุณด้วย3-o >(cat >&3)

นำทุกอย่างมารวมกันในbash 3.2.57(1)-release(มาตรฐานสำหรับ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')

โปรดทราบว่านี้ไม่ทำงานใน/bin/shฐานะSamK ที่ระบุไว้ในความคิดเห็นด้านล่าง


5
มันลื่นมาก ... และฉันก็ชอบมัน!
spyle

3
ทีนี้ฉันจะเปลี่ยนเส้นทางไปยังตัวแปรอื่นได้อย่างไร
Roger Filmyer

1
เอาต์พุตอยู่ในSTDOUTดังนั้นคุณควรจะสามารถเปลี่ยนทิศทางเอาต์พุตจากคำสั่งไปยังที่ใดก็ได้ที่คุณชอบเหมือนกับคำสั่งปกติ ฉันยังไม่ได้ทดสอบสิ่งนี้
Heath Borders

1
ไม่ทำงานกับ / bin / sh
SamK

คำตอบที่ดีคุณยังสามารถเปลี่ยนเส้นทางไปยังไฟล์จริงและวางไว้ในภายหลังหากคุณต้องการพกพาเชลล์ได้
akostadinov

32

กำหนดเอาต์พุต curl ใหม่:

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

สามารถใช้กับคำขอประเภทใดก็ได้


-k (--insecure) กำลังเขียนทับ -s (silent)
Ravichandra

16

รหัสสถานะเท่านั้น

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

เครดิตทั้งหมดของGISTนี้


11

นี่เป็นcurl --failข้อ จำกัด ที่เจ็บปวด จากman curl:

-f, --fail (HTTP) ล้มเหลวอย่างเงียบ ๆ (ไม่มีเอาต์พุตเลย) จากข้อผิดพลาดของเซิร์ฟเวอร์

แต่ไม่มีวิธีรับทั้งรหัสส่งคืนที่ไม่เป็นศูนย์และเนื้อหาการตอบสนองใน stdout

จากคำตอบของpvandenberkและเคล็ดลับที่มีประโยชน์อื่น ๆ ที่ได้เรียนรู้เกี่ยวกับ SOนี่คือวิธีแก้ปัญหา:

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
}

ฟังก์ชันนี้ทำงานตรงตามcurlแต่จะส่งคืน 127 (รหัสส่งคืนที่ไม่ได้ใช้curl) ในกรณีของรหัส HTTP ในช่วง [400, 600 [


เห็นด้วยไม่สามารถที่จะเห็นผลลัพธ์ข้อผิดพลาดเป็นข้อ จำกัด ที่เจ็บปวดของประโยชน์อย่างอื่น --fail คุณสามารถวินิจฉัย REST api ล้มเหลวโดยไม่เห็นผลลัพธ์ข้อผิดพลาดได้อย่างไร เป็นเรื่องที่โชคร้ายที่ผู้ดูแลเครื่องม้วนงหัวชนฝายืนกรานที่จะไม่ให้ข้อผิดพลาด --fail-but-show-show github.com/curl/curl/issues/1978
jamshid

ตามที่ระบุในเอกสารประกอบมันใช้ไม่ได้กับรหัส HTTP 401 และ 407 :(
Logan Mzz

11

สิ่งนี้จะส่งคำขอไปยัง url รับเฉพาะบรรทัดแรกของการตอบกลับแบ่งเป็นบล็อกและเลือกบรรทัดที่สอง

มันมีรหัสการตอบสนอง

curl -I http://example.org 2>/dev/null | head -n 1 | cut -d$' ' -f2

1
คุณช่วยอธิบายได้ว่าโค้ดนี้ทำอะไรและจัดการกับปัญหาที่ได้รับจาก OP หรือไม่ รหัสที่ไม่ได้อธิบายสามารถปรากฏขึ้นไม่น่าเชื่อถือและเป็นอันตรายต่อผู้ใช้
bwDraco

1
แน่นอนว่าเราส่งคำขอไปยัง url รับเฉพาะบรรทัดแรกของการตอบกลับแบ่งเป็นบล็อกและเลือกบรรทัดที่สอง มันมีรหัสการตอบสนองที่ OP กำลังมองหา
Filip Spiridonov

9

สำหรับคำขอ POST การทำงานต่อไปนี้:

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]'

6

ใช้คำสั่ง cURL ต่อไปนี้และไพพ์คำสั่งเพื่อ grep ดังนี้:

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

นี่คือสิ่งที่ธงแต่ละคนทำ:

  • -I: แสดงส่วนหัวการตอบกลับเท่านั้น
  • -s: เงียบ - อย่าแสดงแถบความคืบหน้า
  • -L: ติดตามLocation:ส่วนหัว

นี่คือเชื่อมโยงไปยังรหัสสถานะ HTTP

เรียกใช้จากบรรทัดคำสั่ง Curl นี้ทำงานในโหมดเงียบตามการเปลี่ยนเส้นทางใด ๆ รับส่วนหัว HTTP grep จะพิมพ์รหัสสถานะ HTTP ไปยังเอาต์พุตมาตรฐาน


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

นี่จะส่งคืนข้อมูลต่อไปนี้:

  1. ข้อมูลการตอบกลับหากข้อมูลใด ๆ ถูกส่งคืนโดย API เช่นข้อผิดพลาด
  2. รหัสสถานะ

สิ่งนี้ไม่ได้ติดตามการเปลี่ยนเส้นทาง คำตอบที่มีอยู่นี้ดีกว่าsuperuser.com/a/442395/475508
cricket_007

แน่นอนว่าคุณสามารถอ้างอิงได้เช่นกัน !!
srana

4

นี่คือคำสั่ง curl ที่ใช้GETและที่ส่งคืนรหัส HTTP

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

โปรดจำไว้ว่าวิธีการด้านล่างนี้ใช้HEADซึ่งเร็วกว่า แต่อาจใช้งานได้ไม่ดีกับเซิร์ฟเวอร์ HTTP ที่สอดคล้องกับเว็บบางตัว

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

ไม่ทำงานบน OS X อย่างน้อย
Ain

ทำงานได้ดีสำหรับฉันใน OS X High Sierra 10.13.6
Ben Baron

4

ตัวอย่างของวิธีใช้รหัสตอบกลับ ฉันใช้สิ่งนี้เพื่อดาวน์โหลดฐานข้อมูล Geolite ใหม่เฉพาะเมื่อมีการเปลี่ยนแปลง ( -z) และยังเปลี่ยนเส้นทางต่อไปนี้ ( -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

3

OP ต้องการทราบรหัสสถานะ บ่อยครั้งเมื่อดาวน์โหลดไฟล์คุณต้องรู้สึกถึงขนาดของมันด้วยดังนั้นฉันจึงใช้ curl ก่อนเพื่อแสดงรหัสสถานะและขนาดของไฟล์จากนั้นปิด verbose และส่งตรงไปยังสถานที่และชื่อที่ฉันต้องการ:

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

จากนั้นฉันก็รอให้ม้วนงอ

wait ${!}

ก่อนที่ฉันจะเรียกใช้คำสั่งต่อไป ข้างต้นเมื่อใช้ในสคริปต์ของคำสั่งมากมายเช่นด้านบนให้การตอบสนองที่ดีเช่น:

http: 200 42824

http: 200 34728

http: 200 35452

โปรดทราบว่า -o in curl ต้องตามด้วยเส้นทางแบบเต็มของไฟล์ + ชื่อไฟล์ สิ่งนี้จะช่วยให้คุณสามารถบันทึกไฟล์ในโครงสร้างชื่อที่เหมาะสมเมื่อคุณงอไฟล์ด้วย curl โปรดทราบด้วยว่า -s และ -S ใช้ร่วมกันในการปิดเสียงเอาต์พุต แต่จะแสดงข้อผิดพลาด โปรดทราบว่า -R พยายามตั้งค่าการประทับเวลาของไฟล์เป็นของไฟล์เว็บ

คำตอบของฉันขึ้นอยู่กับสิ่งที่ @pvandenberk แนะนำ แต่แรกเริ่ม แต่นอกจากนี้มันจะบันทึกไฟล์ไว้ที่อื่นแทนการส่งไปยัง / dev / null


1

แยกเนื้อหาเอาต์พุตstdoutและรหัสสถานะ HTTP เป็นstderr:

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

หากต้องการรหัสสถานะ HTTP เท่านั้นถึง stderr --silentสามารถใช้:

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

สตรีมที่ต้องการสามารถเลือกได้โดยเปลี่ยนเส้นทางรายการที่ไม่ต้องการไปที่/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>
...

โปรดทราบว่าสำหรับการเปลี่ยนเส้นทางครั้งที่สองเพื่อทำงานตามที่ต้องการเราจำเป็นต้องเรียกใช้คำสั่ง curl ใน subshell


1
ต้องมีbashการทดแทนกระบวนการ
Jaakko

@Bruno ฉันเปลี่ยนตัวอย่างจากsuperuser.com/revisions/1444693/2เนื่องจากฉันคิดว่า/tmp/out /tmp/errไฟล์อาจทำให้เกิดผลลัพธ์ที่ไม่คาดคิดหากเรียกใช้แบบขนาน
Jaakko
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.