¿Obtener curl para generar el código de estado HTTP?

800

Estoy usando curlla línea de comando en Linux para emitir solicitudes HTTP. Los cuerpos de respuesta se imprimen en estándar, lo cual está bien, pero no puedo ver desde la página del manual cómo obtener curl para imprimir el código de estado HTTP de la respuesta (404, 403, etc.). es posible?

kdt
fuente
En cuanto a mí, puedo ver en el manual cómo obtener el código de estado HTTP, pero la opción -w no funciona. He informado el error a Apple.
Nicolas Barbulesco
19
La -ibandera, como en curl -i https://www.example.com/, es probablemente lo que quieres, según superuser.com/a/514798/190188
caw
¿Por qué no solo algo así curl -IL http://www.example.com | grep "^HTTP\/"?
St3an
De no ser futuro: la respuesta que desea es probablemente Cyril David (actualmente en cuarta posición)
WhiteHotLoveTiger

Respuestas:

524

Esto debería funcionar para usted si el servidor web puede responder a las solicitudes HEAD (esto no realizará a GET):

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

Como complemento, para que cURL siga los redireccionamientos (estados 3xx) agregue -L.

pberlijn
fuente
155
NB: curl -Ihace una solicitud HEAD HTTP, lo que puede ser problemático para probar el código de estado HTTP para algunos servidores y servicios de aplicaciones web
Jay Taylor
16
Y para obtener solo el número de estado, head -n 1|cut -d$' ' -f2
canalícelo
33
No se olvide de redirigir stderr de rizo: curl -I http://www.example.org 2>/dev/null | head -n 1 | cut -d$' ' -f2. Agregue -L al rizo si necesita el estado final después de las redirecciones.
Aaron Blenkush
1
Seguir la redirección después de solo hacer una solicitud HEAD puede causar un comportamiento interesante, dependiendo de cómo esté programada la aplicación.
Scott McIntyre
32
curl -I -X GETenviará una solicitud GET, pero dará el mismo resultado.
jiggy
839

Una forma más específica de imprimir solo el código de estado HTTP es algo similar a:

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

Es mucho más fácil trabajar con scripts, ya que no requiere ningún análisis :-)

El parámetro -Ipodría agregarse para mejorar el rendimiento de la carga de respuesta. Este parámetro solo solicita estado / encabezados de respuesta, sin descargar el cuerpo de respuesta.

Nota: %{http_code} regresa en la primera línea de carga HTTP

es decir:

curl -s -o /dev/null -I -w "%{http_code}" http://www.example.org/
pvandenberk
fuente
54
-w "% {http_code}" es el bit que imprime el código de estado. Puede agregar una nueva línea o dos para separar el código del cuerpo (-w "\ n \ n% {http_code} \ n")
Jeffrey Martinez
77
Wow, esto /dev/nullincluso funciona en la versión de Windows de curl que estoy usando.
Uwe Keim
3
Creo que esto descarga el archivo completo a pesar de que todo va a / dev / null, por lo que no es ideal para verificar el código de estado para archivos grandes. httping -c 1 -s -G -memite un GET y no descarga todo el archivo, aunque me doy cuenta de que esta pregunta es específicamente sobre curl.
RomanSt
40
FYI: -s= No muestra el progreso de la descarga, -o /dev/null= no muestra el cuerpo, -w "%{http_code}"= Escribe el código de respuesta http en stdout después de salir.
Ajedi32
1
¿Se requieren las comillas alrededor del "% {http_code}"?
Hakan Baba
217

Si desea ver el encabezado y el resultado, puede usar la opción detallada:

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

El estado aparecerá en el encabezado. P.ej

< Date: Tue, 04 Nov 2014 19:12:59 GMT
< Content-Type: application/json; charset=utf-8
< Status: 422 Unprocessable Entity
Enrico Susatyo
fuente
26
+1 para señalar la bandera detallada proporciona los detalles adicionales. Ideal para probar aplicaciones REST.
MrOodles
8
+1 muy fácil de usar al hacer una solicitud POST (curl -v --data "...")
MegaTux
1
Incluso los divide en dos salidas de archivo diferentes (detalles de estado http a stderr y cuerpo de respuesta a stdout)
phil294
201

Puede imprimir el código de estado, además de todos los encabezados, haciendo lo siguiente:

curl -i http://example.org

Lo bueno de esto -ies que también funciona -X POST.

Cyril David
fuente
36
Mucho mejor que la respuesta aceptada (que hace una solicitud HEAD).
neu242
10
Quizás sea obvio, pero -ifunciona con cualquier método HTTP, no solo GETy POST... :)
mac
3
la mejor respuesta, ya que hace que la salida del rizo sea tanto en los encabezados como en el cuerpo, lo que lo hace adecuado para la mayoría de las tareas cuando se usa en un script
Sarge Borsch el
66
Esta es la mejor respuesta, y puede usarse junto con -s(no mostrar el medidor de progreso o mensajes de error) y -S(mostrar mensajes de error después de todo)
Jonathan Hartley
69

Si desea capturar el código de estado HTTP en una variable, pero aún así redirigir el contenido a STDOUT, debe crear dos STDOUT. Puede hacerlo con la sustitución de proceso> () y la sustitución de comando $ () .

Primero, cree un descriptor de archivo 3para su proceso actual 'STDOUT with exec 3>&1.

Luego, use la -oopción de curl para redirigir el contenido de la respuesta a una respuesta temporal usando la sustitución de comandos, y luego dentro de esa sustitución de comandos, redirija la salida de nuevo al descriptor de archivo STDOUT del proceso actual 3con -o >(cat >&3).

Poniendo todo junto bash 3.2.57(1)-release(estándar para 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')

Tenga en cuenta que esto no funciona /bin/shcomo SamK señaló en los comentarios a continuación .

Heath Borders
fuente
55
Eso es una mancha seria ... ¡y me gusta!
espía
3
Ahora, ¿cómo, a su vez, puedo redirigir la salida a otra variable?
Roger Filmyer
1
La salida está dentro STDOUT, por lo que debería poder redirigir la salida del comando a cualquier lugar que desee, como un comando normal. Sin embargo, no he probado esto.
Heath Borders
1
No funciona con / bin / sh.
SamK
buena respuesta, también puede redirigir a un archivo real y
capturarlo
32

Redefinir la salida del rizo:

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

Se puede usar con cualquier tipo de solicitud.

Grzegorz Luczywo
fuente
-k (--insecure) está anulando -s (silencio).
Ravichandra
16

Código de estado SOLO

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

Todo el crédito a este GIST

mahatmanich
fuente
11

Esta es una curl --faillimitación dolorosa . De man curl:

-f, --fail (HTTP) Falla silenciosa (sin salida) en errores del servidor

Pero no hay forma de obtener el código de retorno distinto de cero Y el cuerpo de respuesta en stdout.

Basado en la respuesta de pvandenberk y este otro truco muy útil aprendido en SO , aquí hay una solución:

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
}

Esta función se comporta exactamente como curl, pero devolverá 127 (un código de retorno no utilizado por curl) en el caso de un código HTTP en el rango [400, 600 [.

Lucas Cimon
fuente
De acuerdo, no poder ver la salida del error es una limitación dolorosa de lo que de otra manera sería muy útil --fail. ¿Cómo se puede diagnosticar una falla de la API REST sin ver la salida del error? Es tan desafortunado que el mantenedor de rizos bagder insiste obstinadamente en no proporcionar un error --fail-but-show-error. github.com/curl/curl/issues/1978
jamshid
Como se indica en la documentación, no funciona para el código HTTP 401 y 407 :(
Logan Mzz
11

Esto enviará una solicitud a url, obtendrá solo la primera línea de la respuesta, la dividirá en bloques y seleccionará la segunda.

Contiene el código de respuesta.

curl -I http://example.org 2>/dev/null | head -n 1 | cut -d$' ' -f2
Filip Spiridonov
fuente
1
¿Puede explicar qué hace este código y cómo aborda el problema dado por el OP? El código inexplicable puede parecer no confiable y peligroso para los usuarios.
bwDraco
1
Claro, enviamos una solicitud a url, obtenemos solo la primera línea de la respuesta, la dividimos en bloques y seleccionamos la segunda. Contiene el código de respuesta que OP está buscando.
Filip Spiridonov
9

Para una solicitud POST, funcionó lo siguiente:

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
fuente
6

Use el siguiente comando cURL y canalícelo a grep así:

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

Esto es lo que hace cada bandera:

  • -I: Mostrar solo encabezados de respuesta
  • -s: Silencioso - No mostrar barra de progreso
  • -L: Seguir Location:encabezados

Aquí hay un enlace a los códigos de estado HTTP .

Ejecutar desde la línea de comando. Este rizo se ejecuta en modo silencioso, sigue cualquier redireccionamiento, obtiene los encabezados HTTP. grep imprimirá el código de estado HTTP a la salida estándar.

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

Esto devolverá la siguiente información:

  1. datos de respuesta, si la API devuelve algún dato como error
  2. código de estado
srana
fuente
Esto no sigue las redirecciones. Esta respuesta existente es mejor superuser.com/a/442395/475508
cricket_007
¡Claro, puedes referir eso también!
srana
4

Aquí hay un comando curl que está usando GETy que devuelve el código HTTP.

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

Recuerde que está utilizando el siguiente enfoque HEAD, que es más rápido pero puede que no funcione bien con algunos servidores HTTP menos compatibles con la web.

 curl -I http://www.example.org
sorin
fuente
No funciona en OS X al menos.
Ain
Funciona bien para mí en OS X High Sierra 10.13.6.
Ben Baron
4

Un ejemplo de cómo usar los códigos de respuesta. Lo uso para volver a descargar las bases de datos Geolite solo si han cambiado ( -z) y también siguiendo los redireccionamientos ( -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
fuente
3

El OP quiere saber el código de estado. A menudo, al descargar un archivo, también desea tener una idea de su tamaño, así que primero uso curl para mostrar el código de estado y el tamaño del archivo y luego apago el archivo detallado y directo al lugar y el nombre que quiero:

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

Entonces espero a que termine el rizo

wait ${!}

antes de ejecutar el siguiente comando. Lo anterior cuando se usa en un script de muchos comandos como el anterior da una buena respuesta como:

http: 200 42824

http: 200 34728

http: 200 35452

Tenga en cuenta que -o in curl debe ser seguido por la ruta completa del archivo + nombre del archivo. Esto le permite guardar archivos en una estructura de nombre sensible cuando los d / l con curl. También tenga en cuenta que -s y -S usados ​​juntos silencian la salida pero muestran errores. Tenga en cuenta también que -R intenta establecer la marca de tiempo del archivo en la del archivo web.

Mi respuesta se basa en lo que @pvandenberk sugirió originalmente, pero además en realidad guarda el archivo en algún lugar, en lugar de simplemente dirigirlo a / dev / null.

sakumatto
fuente
1

Divida el contenido de salida stdouty el código de estado HTTP para stderr:

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

Si solo se desea el código de estado HTTP para stderr, --silentpuede usarse:

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

La secuencia deseada se puede seleccionar redirigiendo una no deseada a /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>
...

Tenga en cuenta que para que la segunda redirección se comporte como lo deseamos, necesitamos ejecutar el comando curl en subshell.

Jaakko
fuente
1
Requiere bashpara la sustitución del proceso.
Jaakko
@Bruno, cambié el ejemplo de superuser.com/revisions/1444693/2 , ya que creo que los /tmp/out /tmp/errarchivos pueden causar resultados inesperados si se ejecutan en paralelo.
Jaakko