2011-04-18 10:28:57 +0000 2011-04-18 10:28:57 +0000
864
864

¿Consiguiendo que Curl emita el código de estado HTTP?

Estoy usando curl en la línea de comandos en Linux para emitir peticiones HTTP. Los cuerpos de respuesta se imprimen de forma estándar, lo cual está bien, pero no puedo ver en la página de manual cómo conseguir que curl imprima el código de estado HTTP de la respuesta (404, 403 etc). ¿Es esto posible?

Respuestas (16)

906
906
906
2012-06-28 00:25:11 +0000

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

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

Mucho más fácil de trabajar en los scripts, ya que no requiere ningún tipo de análisis :-)

El parámetro -I podría ser añadido para mejorar el rendimiento de la carga de respuesta. Este parámetro sólo solicita el estado/cabezas de respuesta, sin descargar el cuerpo de respuesta.

Nota: %{http_code} devuelve en la primera línea de la carga útil HTTP

es decir:

curl -s -o /dev/null -I -w "%{http_code}" http://www.example.org/
572
572
572
2011-04-18 10:56:02 +0000

Esto debería funcionar para ti si el servidor web es capaz de responder a las peticiones HEAD (esto no realizará un GET):

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

Como adición, para dejar que cURL siga las redirecciones (3xx estados) añade -L.

237
237
237
2012-05-03 04:28:44 +0000

Si quieres ver el encabezado así como el resultado, puedes usar la opción verbosa:

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

El estado aparecerá en el encabezado. Por ejemplo,

< Date: Tue, 04 Nov 2014 19:12:59 GMT
< Content-Type: application/json; charset=utf-8
< Status: 422 Unprocessable Entity
218
218
218
2012-12-04 20:45:49 +0000

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

curl -i http://example.org

Lo bueno de -i es que funciona con -X POST también.

71
71
71
2015-01-08 20:59:43 +0000

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

Primero, crea un descriptor de archivo 3 para el STDOUT de tu proceso actual con exec 3>&1.

Luego, usa la opción -o de curl para redirigir el contenido de la respuesta a una fifo temporal usando la sustitución de comandos, y luego dentro de esa sustitución de comandos, redirige la salida de vuelta a tu proceso actual STDOUT descriptor de archivo 3 con -o >(cat >&3).

Poniendo todo junto en 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')

Nota que esto no funciona en /bin/sh como SamK anotado en los comentarios de abajo .

35
35
35
2014-08-05 18:18:29 +0000

Redefina la salida del rizo:

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

Puede ser usado con cualquier tipo de solicitud.

19
19
19
2017-02-08 10:44:15 +0000

Código de estado Sólo

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

Todo el crédito a este GIST

14
14
14
2016-04-06 13:08:49 +0000

Esta es una dolorosa limitación curl --fail. Desde man curl :

-f, –fail (HTTP) Falla silenciosamente (no hay ninguna salida) en los errores del servidor

Pero no hay manera de obtener tanto el código de retorno no 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 usado por curl) en caso de un código HTTP en el rango [400, 600[.

11
11
11
2015-07-15 20:08:53 +0000

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

Contiene el código de la respuesta

curl -I http://example.org 2>/dev/null | head -n 1 | cut -d$' ' -f2
9
9
9
2016-01-07 08:36:07 +0000

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]'
6
6
6
2016-11-21 11:28:27 +0000

Usa el siguiente comando cURL y guíalo para grepar así:

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

Esto es lo que hace cada bandera:

  • -I: Mostrar sólo los encabezados de respuesta
  • -s: Silencio - No mostrar barra de progreso
  • -L: Sigue los encabezados Location:

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

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

5
5
5
2017-03-08 05:12:46 +0000
curl -so -i /dev/null -w "%{http_code}" http://www.any_example.com

Esto devolverá la siguiente información:

  1. datos de respuesta, si algún dato es devuelto por el API como error
  2. código de estado
4
4
4
2016-06-23 10:37:18 +0000

Aquí hay un comando curl que usa GET y que devuelve el código HTTP.

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

Por favor, recuerde que el enfoque de abajo es usar HEAD, que es más rápido pero puede no funcionar bien con algunos servidores HTTP menos compatibles con la web.

curl -I http://www.example.org
4
4
4
2018-04-01 17:21:59 +0000

Un ejemplo de cómo utilizar los códigos de respuesta. Lo uso para volver a descargar las bases de datos de Geolite sólo si han cambiado (-z) y también siguiendo las redirecciones (-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
3
3
2017-10-07 07:32:50 +0000

La Oficina de Operaciones quiere saber el código de estado. A menudo, cuando se descarga un archivo, también se quiere tener una idea de su tamaño, así que uso curl primero para mostrar el código de estado y el tamaño del archivo y luego apago el archivo verboso y lo dirijo al lugar y 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

Luego espero a que termine el curl

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 en curl necesita ser seguido por la ruta completa del archivo + nombre del archivo. Esto le permite, por lo tanto, guardar los archivos en una estructura de nombres sensata cuando los d/l con curl. También tenga en cuenta que la -s y la -S usadas juntas silencian la salida pero muestran errores. Observe también que -R intenta establecer la marca de tiempo del archivo a la del archivo web.

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

1
1
1
2019-06-04 08:08:22 +0000

Dividir el contenido de la salida a stdout y el código de estado HTTP a stderr:

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

Si sólo se desea el código de estado HTTP para stderr, se puede usar --silent:

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

El flujo deseado se puede elegir entonces redirigiendo el no deseado 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>
...

Nota que para que la segunda redirección se comporte como se desea, necesitamos ejecutar el comando curl en subshell.