Tôi có thể khiến cURL thất bại với exitCode khác 0 không nếu mã trạng thái HTTP không phải là 200?


239

Tôi đã luôn cho rằng khi curl nhận được phản hồi HTTP 500 thì nó đã trả về mã thoát có nghĩa là thất bại (! = 0), nhưng dường như không phải vậy.

Có cách nào để tôi có thể khiến cURL thất bại với exitCode khác 0 nếu mã trạng thái HTTP không phải là 200 không? Tôi biết tôi có thể sử dụng -w "%{http_code}"nhưng điều đó đặt nó trong STDOUT, không phải là mã thoát (bên cạnh đó, tôi cũng quan tâm đến việc nắm bắt đầu ra, điều mà tôi không muốn chuyển hướng đến một tệp, nhưng đến màn hình).

Câu trả lời:


263

curl --fail thực hiện một phần những gì bạn muốn:

từ man curl:

-f, --fail

(HTTP) Lỗi âm thầm (không có đầu ra nào) đối với các lỗi máy chủ. Điều này chủ yếu được thực hiện để kích hoạt tốt hơn các kịch bản vv để đối phó tốt hơn với các lần thử thất bại. Trong các trường hợp bình thường khi máy chủ HTTP không gửi được tài liệu, nó sẽ trả về một tài liệu HTML ghi rõ (thường cũng mô tả lý do tại sao và hơn thế nữa). Cờ này sẽ ngăn cuộn tròn xuất ra và trả về lỗi 22.

Phương pháp này không an toàn và có những lúc mã phản hồi không thành công sẽ bị trượt, đặc biệt là khi xác thực có liên quan (mã phản hồi 401 và 407).

Nhưng nó chặn đầu ra màn hình.


2
Vì vậy, những phần của nó làm và không làm?
rogerdpack

5
@rogerdpack tl; dr nó sẽ trả về giá trị khác khi phát hiện phản hồi xấu, nhưng nó sẽ không cho phép OP nắm bắt phản hồi
hung hăng

3
Điều này không bắt được HTTP 301 Move Vĩnh viễn. curl vẫn đưa ra mã thoát 0.
wvducky

4
@wisbucky 301 không phải là lỗi, đó là mã trạng thái chuyển hướng. Lỗi là mã trạng thái 4xx và 5xx.
M. Justin

1
@wvducky để thoát nonzero trên mã lỗi HTTP xử lý chuyển hướng HTTP sử dụng chính xác curl -f -Lvà xem câu hỏi này để biết chi tiết về những gì -L.

81

Nếu bạn chỉ muốn hiển thị nội dung của trang cuộn tròn, bạn có thể làm điều này:

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

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

Điều này ghi nội dung của trang vào STDERR trong khi viết mã trạng thái HTTP sang STDOUT, do đó, nó có thể được gán cho biến STATUSCODE .


3
Sẽ thế nào nếu tôi muốn xuất phản hồi khi thất bại (không phải 200) , nhưng trả lại 0mã không trạng thái từ tập lệnh?
Justin

2
@Justin: Thế còn if [ "$statuscode" -ne 200 ]; then exit "$statuscode"; fi?
ghoti

4
@ghoti: Chỉ hỗ trợ mã thoát 8 bit không dấu, do đó có thể gây nhầm lẫn một chút.
Dennis

3
À, phải - và mã sẽ gói ở 8 bit, do đó, lỗi 404 trở thành giá trị thoát 148, 500 trở thành 244. Thật khó hiểu! :-)
ghoti

7
Là một biến thể nhỏ, điều này ghi lại mã trong một biến trong khi chuyển hướng phản hồi đến thiết bị xuất chuẩn, không phải tiêu chuẩn: { code=$(curl ... as above ...); } 2>&1Thủ thuật là { ... } 2>&1cho phép chuyển hướng, trong khi không sinh ra một vỏ khác như mong ( ... )muốn.
Tobia

31

Tôi đã có thể làm điều đó bằng cách sử dụng kết hợp các cờ:

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

--silent ẩn tiến trình và lỗi
--show-error hiển thị thông báo lỗi được ẩn bởi --silent
--fail trả về mã thoát> 0 khi yêu cầu không thành công


5
Điều này không hiển thị trả lời máy chủ. Tôi không phải là OP nhưng tôi nghi ngờ anh ta muốn xem bất kỳ thông báo lỗi nào từ máy chủ được trả lại trong cơ thể. Bên cạnh đó một --silent --show-error --failcông trình giống như chỉ -f/--fail.
lãng phí

1
Trên thực tế, --failtrả về mã thoát 22, như tài liệu .
Câu hỏi Quolonel

2
@wisbucky 301 không phải là lỗi, đó là mã trạng thái chuyển hướng. Lỗi là mã trạng thái 4xx và 5xx.
M. Justin

4
Để công bằng cho @wisbucky, câu hỏi ban đầu nêu rõ "[...] nếu mã trạng thái HTTP không phải là 200" . Không đề cập đến "lỗi" bất cứ nơi nào trước.
ken

2
@ M.Justin Theo curl man-page: Phương pháp này không an toàn và có những lúc mã phản hồi không thành công sẽ bị trượt, đặc biệt là khi có xác thực (mã phản hồi 401 và 407).
youfu

0

Có một cách để làm điều đó nhưng không rõ ràng vì nó liên quan đến 3 tùy chọn cuộn tròn:

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

Điều này đảm bảo rằng thành công (0) chỉ xảy ra khi curl kết thúc chúng tôi với 2xxmã trả lại cuối cùng và điều đó stdoutcó được phần thân và rằng bất kỳ lỗi nào sẽ được hiển thị cho stderr.

Xin lưu ý rằng tài liệu curl có thể làm bạn bối rối một chút vì nó đề cập rằng --fail có thể thành công đối với một số mã 401. Dựa trên các thử nghiệm không đúng, ít nhất là không khi được sử dụng với --show-error cùng một lúc.

Cho đến nay tôi không thể tìm thấy bất kỳ trường hợp nào mà curl sẽ trở lại thành công khi nó không phải là một http-succeds với các tùy chọn này.


1
đây có phải là câu trả lời cơ bản giống như của Ricardo Souza không?
knocte
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.