ฉันสามารถทำให้ cURL ล้มเหลวด้วย exitCode ที่แตกต่างจาก 0 ได้หรือไม่หากรหัสสถานะ HTTP ไม่ใช่ 200


239

ฉันมักจะสมมติว่าเมื่อ curl ได้รับการตอบสนอง HTTP 500 มันกลับรหัสทางออกที่หมายถึงความล้มเหลว (! = 0) แต่ที่ดูเหมือนจะไม่เป็นกรณี

มีวิธีที่ฉันสามารถทำให้ cURL ล้มเหลวด้วย exitCode ที่แตกต่างจาก 0 ถ้ารหัสสถานะ HTTP ไม่ได้ 200? ฉันรู้ว่าฉันสามารถใช้งานได้-w "%{http_code}"แต่ใส่ไว้ใน STDOUT ไม่ใช่รหัสออก (นอกจากนี้ฉันยังสนใจที่จะจับเอาท์พุทซึ่งฉันไม่ต้องการเปลี่ยนเส้นทางไปยังไฟล์ แต่ไปที่หน้าจอ)

คำตอบ:


263

curl --fail เป็นส่วนหนึ่งของสิ่งที่คุณต้องการ:

จากman curl:

-f, --fail

(HTTP) ล้มเหลวอย่างเงียบ ๆ (ไม่มีเอาต์พุตเลย) เนื่องจากข้อผิดพลาดของเซิร์ฟเวอร์ ส่วนใหญ่จะทำเพื่อให้สคริปต์ ฯลฯ สามารถจัดการกับความพยายามที่ล้มเหลวได้ดีขึ้น ในกรณีปกติเมื่อเซิร์ฟเวอร์ HTTP ไม่สามารถส่งเอกสารได้จะส่งคืนเอกสาร HTML ที่ระบุเช่นนั้น (ซึ่งมักจะอธิบายสาเหตุและอื่น ๆ ) การตั้งค่าสถานะนี้จะป้องกันไม่ให้ขดออกผลลัพธ์นั้นและกลับข้อผิดพลาด 22

วิธีนี้ไม่ปลอดภัยและมีหลายครั้งที่รหัสการตอบสนองที่ไม่สำเร็จจะส่งผ่านโดยเฉพาะอย่างยิ่งเมื่อมีการตรวจสอบสิทธิ์ (รหัสตอบสนอง 401 และ 407)

แต่จะบล็อกเอาต์พุตไปที่หน้าจอ


2
แล้วส่วนไหนของมันที่ทำและไม่ทำ?
rogerdpack

5
@rogerdpack tl; dr จะส่งคืนค่าที่ไม่ใช่ศูนย์เมื่อตรวจพบการตอบสนองที่ไม่ดี แต่จะไม่ยอมให้ OP บันทึกการตอบกลับ
rampion

3
สิ่งนี้ไม่ได้รับ HTTP 301 Move อย่างถาวร ขดยังคงให้รหัสออก 0
wisbucky

4
@wisbucky 301 ไม่ใช่ข้อผิดพลาดเป็นรหัสสถานะการเปลี่ยนเส้นทาง ข้อผิดพลาดคือรหัสสถานะ 4xx และ 5xx
M. Justin

1
@wisbucky เพื่อออกจากไม่ใช่ศูนย์บนรหัสข้อผิดพลาด HTTP และจัดการการเปลี่ยนเส้นทาง HTTP ให้ใช้อย่างถูกต้องcurl -f -Lและดูคำถามนี้เพื่อดูรายละเอียดเกี่ยวกับสิ่งที่-Lทำ
Noah Sussman

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รหัสสถานะที่ไม่ใช่จากสคริปต์
Justin

2
@Justin: เกี่ยวกับif [ "$statuscode" -ne 200 ]; then exit "$statuscode"; fiอะไร
ghoti

4
@ghoti: รองรับเฉพาะรหัสทางออก 8 บิตที่ไม่ได้ลงชื่อดังนั้นอาจทำให้เกิดความสับสนเล็กน้อย
Dennis

3
อ่าขวา - และรหัสจะห่อที่ 8 บิตดังนั้นข้อผิดพลาด 404 กลายเป็นค่าออก 148, 500 กลายเป็น 244 สับสนแน่นอน! :-)
ghoti

7
ในฐานะที่เป็นความแตกต่างเล็กน้อยนี้จับรหัสในตัวแปรในขณะที่เปลี่ยนเส้นทางการตอบสนองไปยัง stdout ไม่ใช่ stderr: { code=$(curl ... as above ...); } 2>&1เคล็ดลับ{ ... } 2>&1ที่ช่วยให้การเปลี่ยนเส้นทางในขณะที่ไม่วางไข่เปลือกที่แตกต่างกันตามที่( ... )จะ
Tobia

31

ฉันสามารถทำได้โดยใช้การรวมกันของธง:

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

- เงียบซ่อนความคืบหน้าและข้อผิดพลาด
-แสดงข้อผิดพลาดแสดงข้อความข้อผิดพลาดที่ซ่อนโดย--silent
--failส่งกลับรหัสทางออก> 0 เมื่อคำขอล้มเหลว


5
นี่ไม่แสดงการตอบกลับของเซิร์ฟเวอร์ ฉันไม่ใช่ OP แต่ฉันสงสัยว่าเขาต้องการเห็นข้อความแสดงข้อผิดพลาดจากเซิร์ฟเวอร์ซึ่งส่งคืนเป็นเนื้อหา นอกจากทำงานเหมือนกับเพียง--silent --show-error --fail -f/--fail
เสีย

1
ที่จริงแล้ว--failกลับรหัสทางออก22, เป็นเอกสาร
คำถาม Quolonel

2
@wisbucky 301 ไม่ใช่ข้อผิดพลาดเป็นรหัสสถานะการเปลี่ยนเส้นทาง ข้อผิดพลาดคือรหัสสถานะ 4xx และ 5xx
M. Justin

4
เพื่อความเป็นธรรมกับ @wisbucky, รัฐคำถามเดิม"[ ... ] ถ้ารหัสสถานะ HTTP ไม่ได้เป็น 200" ไม่มีการกล่าวถึง "ข้อผิดพลาด" ที่ใด ๆ มาก่อน
เคน

2
@ M.Justin อ้างอิงจาก curl man-page: วิธีนี้ไม่ปลอดภัยและมีโอกาสที่รหัสการตอบสนองที่ไม่สำเร็จจะลื่นไหลโดยเฉพาะอย่างยิ่งเมื่อมีการตรวจสอบสิทธิ์ (รหัสตอบสนอง 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

สิ่งนี้ทำให้มั่นใจได้ว่าความสำเร็จ (0) เกิดขึ้นเฉพาะเมื่อ curl-end เราด้วย2xxรหัสส่งคืนสุดท้ายและstdoutทำให้ร่างกายได้รับและข้อผิดพลาดใด ๆ จะถูกแสดงไปยัง stderr

โปรดทราบว่าเอกสาร curl อาจทำให้คุณสับสนเล็กน้อยเนื่องจากระบุว่า - ไฟล์อาจประสบความสำเร็จสำหรับรหัส 401 บางรหัส จากการทดสอบที่ไม่เป็นความจริงอย่างน้อยก็ไม่ได้เมื่อใช้กับ --show-error ในเวลาเดียวกัน

จนถึงตอนนี้ฉันไม่สามารถค้นหากรณีใด ๆ ที่ขดจะกลับมาประสบความสำเร็จเมื่อมันไม่ใช่ http-succeds กับตัวเลือกเหล่านี้


1
นี่เป็นคำตอบเดียวกับ Ricardo Souza หรือไม่
knocte
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.