Bắt curl để xuất mã trạng thái HTTP?


800

Tôi đang sử dụng curltại dòng lệnh trên Linux để phát hành các yêu cầu HTTP. Các nội dung phản hồi được in ra theo tiêu chuẩn, điều này rất tốt, nhưng tôi không thể xem từ trang hướng dẫn cách cuộn tròn để in mã trạng thái HTTP từ phản hồi (404, 403, v.v.). Điều này có thể không?


Đối với tôi, tôi có thể xem từ hướng dẫn cách lấy mã trạng thái HTTP, nhưng tùy chọn -w không hoạt động. Tôi đã báo cáo lỗi cho Apple.
Nicolas Barbulesco

19
Các -icờ, như trong curl -i https://www.example.com/, có lẽ là những gì bạn muốn, theo superuser.com/a/514798/190188
caw

Tại sao không chỉ một cái gì đó giống như curl -IL http://www.example.com | grep "^HTTP\/"?
St3an

Không tương lai: câu trả lời bạn muốn có lẽ là của Cyril David (hiện đang ở vị trí thứ 4)
WhiteHotLoveTiger

Câu trả lời:


526

Điều này sẽ phù hợp với bạn nếu máy chủ web có thể đáp ứng các yêu cầu CHÍNH (điều này sẽ không thực hiện a GET):

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

Ngoài ra, để cho cURL theo dõi chuyển hướng (trạng thái 3xx) thêm -L.


155
NB: curl -Ithực hiện một yêu cầu HTTP CHÍNH, có thể có vấn đề khi kiểm tra mã trạng thái HTTP cho một số máy chủ và dịch vụ ứng dụng web
Jay Taylor

16
Và để chỉ lấy số trạng thái, hãy chuyển nó sanghead -n 1|cut -d$' ' -f2
Benubird

33
Đừng quên chuyển hướng stderr của curl : curl -I http://www.example.org 2>/dev/null | head -n 1 | cut -d$' ' -f2. Thêm -L để cuộn tròn nếu bạn cần trạng thái cuối cùng sau khi chuyển hướng.
Aaron Blenkush

1
Thực hiện theo chuyển hướng sau khi chỉ thực hiện một yêu cầu CHÍNH có thể gây ra hành vi thú vị, tùy thuộc vào cách ứng dụng được lập trình.
Scott McIntyre

31
curl -I -X GETsẽ gửi yêu cầu GET, nhưng đưa ra cùng một đầu ra.
nhộn

835

Một cách cụ thể hơn để in ra chỉ mã trạng thái HTTP là một cái gì đó dọc theo dòng:

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

Làm việc với các tập lệnh dễ dàng hơn nhiều, vì nó không yêu cầu bất kỳ phân tích cú pháp nào :-)

Tham số -Icó thể được thêm vào để cải thiện hiệu suất tải phản hồi. Tham số này chỉ yêu cầu trạng thái / tiêu đề phản hồi, không có phần phản hồi tải xuống.

Lưu ý: %{http_code} trả về dòng đầu tiên của tải trọng HTTP

I E:

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

54
-w "% {http_code}" là bit in mã trạng thái. Bạn có thể thêm một hoặc hai dòng mới vào đó để tách mã khỏi phần thân (-w "\ n \ n% {http_code} \ n")
Jeffrey Martinez

7
Wow, điều này /dev/nullthậm chí hoạt động trong phiên bản Windows curl mà tôi đang sử dụng.
Uwe Keim

3
Tôi tin rằng điều này tải xuống toàn bộ tệp mặc dù tất cả đều chuyển sang / dev / null, vì vậy không lý tưởng để kiểm tra mã trạng thái cho các tệp lớn. httping -c 1 -s -G -mphát hành một GET và không tải xuống toàn bộ tập tin, mặc dù tôi nhận ra câu hỏi này là cụ thể về curl.
RomanSt

40
FYI: -s= Không hiển thị tiến trình tải xuống, -o /dev/null= không hiển thị phần thân, -w "%{http_code}"= Viết mã phản hồi http vào thiết bị xuất chuẩn sau khi thoát.
Ajedi32

1
Các trích dẫn xung quanh "% {http_code}" có bắt buộc không?
Hakan Baba

217

Nếu bạn muốn xem tiêu đề cũng như kết quả, bạn có thể sử dụng tùy chọn dài dòng:

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

Trạng thái sẽ xuất hiện trong tiêu đề. Ví dụ

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

26
+1 để chỉ ra cờ dài cung cấp các chi tiết bổ sung. Tuyệt vời để thử nghiệm các ứng dụng REST.
MrOodles

8
+1 rất dễ sử dụng khi thực hiện yêu cầu POST (curl -v --data "...")
MegaTux

1
Nó thậm chí còn chia chúng thành hai đầu ra tệp khác nhau (chi tiết trạng thái http cho thiết bị xuất chuẩn và phản hồi cho thiết bị xuất chuẩn)
Blauhirn

201

Bạn có thể in mã trạng thái, ngoài tất cả các tiêu đề bằng cách thực hiện như sau:

curl -i http://example.org

Điều tốt -ilà nó cũng hoạt động với -X POST.


36
Tốt hơn nhiều so với câu trả lời được chấp nhận (yêu cầu CHÍNH).
neu242

10
Có thể rõ ràng, nhưng -ikhông hoạt động với bất kỳ phương thức HTTP nào , không chỉ GETPOST... :)
mac

3
câu trả lời tốt nhất vì nó làm cho đầu ra cong cả phần đầu và phần thân, làm cho nó phù hợp với hầu hết các tác vụ khi được sử dụng trong tập lệnh
SUND Borsch

6
Đây là câu trả lời tốt nhất và có thể được sử dụng cùng với -s(không hiển thị đồng hồ đo tiến độ hoặc thông báo lỗi) và -S(hiển thị thông báo lỗi sau tất cả)
Jonathan Hartley

69

Nếu bạn muốn chụp mã trạng thái HTTP trong một biến, nhưng vẫn chuyển hướng nội dung sang STDOUT, bạn phải tạo hai STDOUT. Bạn có thể làm như vậy với quá trình thay thế> ()thay thế lệnh $ () .

Đầu tiên, tạo một bộ mô tả tệp 3cho quy trình hiện tại của bạn 'STDOUT với exec 3>&1.

Sau đó, sử dụng -otùy chọn của curl để chuyển hướng nội dung phản hồi sang fifo tạm thời bằng cách sử dụng thay thế lệnh và sau đó trong lệnh thay thế đó, chuyển hướng đầu ra trở lại mô tả tệp STDOUT quy trình hiện tại của bạn 3với -o >(cat >&3).

Đặt tất cả lại với nhau trong bash 3.2.57(1)-release(tiêu chuẩn cho 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')

Lưu ý rằng điều này không hoạt động /bin/shnhư SamK đã lưu ý trong các bình luận bên dưới .


5
Đó là sự nhếch nhác nghiêm trọng ... và tôi thích nó!
spyle

3
Bây giờ, làm thế nào để tôi có thể chuyển hướng đầu ra sang một biến khác?
Roger Filmyer

1
Đầu ra là trong STDOUT, vì vậy bạn sẽ có thể chuyển hướng đầu ra từ lệnh đến bất cứ nơi nào bạn muốn giống như một lệnh thông thường. Tôi đã không kiểm tra điều này mặc dù.
Heath Biên giới

1
Không hoạt động với / bin / sh.
SamK

câu trả lời hay, bạn cũng có thể chuyển hướng đến một tập tin thực và gửi nó sau nếu bạn muốn tính di động của shell
akostadinov

32

Xác định lại đầu ra curl:

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

Có thể được sử dụng với bất kỳ loại yêu cầu.


-k (- bảo mật) đang ghi đè -s (im lặng).
Ravichandra

16

Mã trạng thái CHỈ

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

Tất cả tín dụng cho GIST này


11

Đây là một curl --failhạn chế đau đớn . Từ man curl:

-f, --fail (HTTP) Lỗi âm thầm (không có đầu ra nào cả) do lỗi máy chủ

Nhưng không có cách nào để có được cả mã trả về khác không phần thân phản hồi trong thiết bị xuất chuẩn.

Dựa trên câu trả lời của pvandenberkthủ thuật rất hữu ích khác được học trên SO , đây là một cách giải quyết:

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
}

Hàm này hoạt động chính xác như curl, nhưng sẽ trả về 127 (mã trả về không được sử dụng bởi curl) trong trường hợp mã HTTP trong phạm vi [400, 600 [.


Đồng ý, không thể thấy đầu ra lỗi là một hạn chế đau đớn của - rất tiện lợi. Làm thế nào bạn có thể chẩn đoán lỗi api REST mà không thấy đầu ra lỗi? Thật đáng tiếc khi người bảo trì uốn cong ngoan cố khăng khăng không cung cấp một lỗi - lỗi nhưng hiển thị. github.com/curl/curl/issues/1978
jamshid

Như đã nêu trong tài liệu, nó không hoạt động đối với mã HTTP 401 và 407 :(
Logan Mzz

11

Điều này sẽ gửi yêu cầu tới url, chỉ nhận dòng đầu tiên của phản hồi, tách nó thành các khối và chọn cái thứ hai.

Nó chứa mã phản hồi

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

1
Bạn có thể giải thích mã này làm gì và cách giải quyết vấn đề do OP đưa ra không? Mã không giải thích được có thể xuất hiện không đáng tin cậy và nguy hiểm cho người dùng.
bwDraco 16/07/2015

1
Chắc chắn, chúng tôi gửi yêu cầu tới url, chỉ nhận dòng đầu tiên của phản hồi, tách nó thành các khối và chọn cái thứ hai. Nó chứa mã phản hồi mà OP đang tìm kiếm.
Filip Spiridonov

9

Đối với một yêu cầu POST, sau đây đã hoạt động:

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

Sử dụng lệnh cURL sau đây và chuyển nó thành grep như vậy:

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

Đây là những gì mỗi cờ làm:

  • -I: Chỉ hiển thị tiêu đề phản hồi
  • -s: Im lặng - Không hiển thị thanh tiến trình
  • -L: Theo dõi Location:các tiêu đề

Đây là một liên kết đến mã trạng thái HTTP .

Chạy từ dòng lệnh. Curl này chạy trong chế độ im lặng, theo bất kỳ chuyển hướng nào, nhận các tiêu đề HTTP. grep sẽ in mã trạng thái HTTP thành đầu ra tiêu chuẩn.


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

Điều này sẽ trả về các thông tin sau:

  1. dữ liệu phản hồi, nếu bất kỳ dữ liệu nào được API trả về như lỗi
  2. mã trạng thái

Điều này không theo chuyển hướng. Câu trả lời hiện có này là superuser
hơn.com/a/442395/475508

Chắc chắn, bạn cũng có thể tham khảo điều đó !!
srana

4

Đây là một số lệnh curl đang sử dụng GETvà trả về mã HTTP.

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

Xin nhớ rằng cách tiếp cận bên dưới đang sử dụng HEAD, nhanh hơn nhưng có thể không hoạt động tốt với một số máy chủ HTTP ít tuân thủ web.

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

Không hoạt động trên OS X ít nhất.
Ain

Làm việc tốt với tôi trên OS X High Sierra 10.13.6.
Ben Baron

4

Một ví dụ về cách sử dụng mã phản hồi. Tôi sử dụng điều này để tải xuống lại cơ sở dữ liệu Geolite chỉ khi chúng đã thay đổi ( -z) và cũng theo các chuyển hướng ( -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 muốn biết mã trạng thái. Thông thường khi tải xuống một tệp bạn cũng muốn cảm nhận về kích thước của nó, vì vậy trước tiên tôi sử dụng curl để hiển thị mã trạng thái và kích thước của tệp, sau đó tắt verbose và gửi tệp trực tiếp đến địa điểm và tên tôi muốn:

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

Sau đó, tôi chờ đợi sự hoàn thiện của curl

wait ${!}

trước khi tôi chạy lệnh tiếp theo. Ở trên khi được sử dụng trong một tập lệnh gồm nhiều lệnh như trên sẽ cho một phản hồi tốt như:

http: 200 42824

http: 200 34728

http: 200 35452

Xin lưu ý rằng -o trong curl cần phải được theo sau bởi đường dẫn đầy đủ của tệp + tên của tệp. Điều này cho phép bạn lưu các tệp theo cấu trúc tên hợp lý khi bạn thực hiện chúng với độ cong. Cũng lưu ý rằng -s và -S được sử dụng cùng nhau làm im lặng đầu ra nhưng không hiển thị lỗi. Cũng lưu ý rằng -R cố gắng đặt dấu thời gian của tệp thành dấu thời gian của tệp web.

Câu trả lời của tôi dựa trên những gì @pvandenberk đề xuất ban đầu, nhưng ngoài ra nó thực sự lưu tệp ở đâu đó, thay vì chỉ chuyển đến / dev / null.


1

Tách nội dung đầu ra thành stdoutvà mã trạng thái HTTP thành stderr:

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

Nếu chỉ mã trạng thái HTTP được mong muốn cho thiết bị lỗi chuẩn, --silentcó thể được sử dụng:

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

Luồng mong muốn sau đó có thể được chọn bằng cách chuyển hướng một luồng không mong muốn sang /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>
...

Lưu ý rằng để chuyển hướng thứ hai hoạt động như mong muốn, chúng ta cần chạy lệnh curl trong subshell.


1
Yêu cầu bashthay thế quá trình.
Jaakko

@Bruno, tôi đã thay đổi ví dụ từ superuser.com/revutions/1444693/2 , vì tôi nghĩ các /tmp/out /tmp/errtệp có thể gây ra kết quả không mong muốn nếu chạy song song.
Jaakko
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.