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

Obtendo o curl para sair o código de status HTTP?

Estou usando o curl na linha de comando no Linux para emitir pedidos HTTP. Os corpos de resposta são impressos de acordo com o padrão, o que é óptimo, mas não consigo ver na página de manual como obter o curl para imprimir o código de estado HTTP da resposta (404, 403, etc). Isto é possível?

Respostas (16)

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

Uma forma mais específica de imprimir just o código de estado HTTP é algo do tipo:

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

Muito mais fácil de trabalhar em scripts, uma vez que não requer qualquer análise :-)

O parâmetro -I pode ser adicionado para melhorar o desempenho da carga de resposta. Este parâmetro apenas solicita estado/cabeçalhos de resposta, sem corpo de resposta de download.

Nota: %{http_code} regressa na primeira linha de carga útil HTTP

i.e.:

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

Isto deve funcionar para si if o servidor web é capaz de responder a pedidos HEAD (isto não irá executar um GET):

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

Como adição, para deixar o cURL seguir redireccionamentos (3xx estados) adicionar -L.

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

Se quiser ver o cabeçalho, bem como o resultado, pode usar a opção verbosa:

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

O estado aparecerá no cabeçalho. Por exemplo:

< 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

Pode imprimir o código de estado, para além de todos os cabeçalhos, fazendo o seguinte:

curl -i http://example.org

O bom do -i é que também funciona com o -X POST.

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

Se você quiser capturar o código de status HTTP em uma variável, mas ainda assim redirecionar o conteúdo para STDOUT, você deve criar duas STDOUTs. Pode fazê-lo com process substitution >() e command substitution $() .

Primeiro, crie um descritor de ficheiro 3 para o STDOUT do seu processo actual com exec 3>&1.

Depois, utilize a opção curl’s -o para redireccionar o conteúdo da resposta para um ficheiro temporário, utilizando o comando de substituição, e depois, dentro desse comando de substituição, redireccione a saída de volta para o seu processo actual STDOUT, o descritor de ficheiros 3 com -o >(cat >&3).

Juntando tudo em bash 3.2.57(1)-release (padrão 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')

Note que isto não funciona em /bin/sh como SamK notou nos comentários abaixo .

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

Redefinir a saída de ondulação:

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

Pode ser usado com qualquer tipo de pedido.

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

Código de situação ONLY

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

Todos os créditos a este GIST

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

Esta é uma limitação dolorosa curl --fail. De man curl :

-f, –fail (HTTP) Falha silenciosamente (sem saída) nos erros do servidor

Mas não há maneira de obter ambos os códigos de retorno não zero E o corpo de resposta em stdout.

Baseado na resposta de pvandenberk e este outro truque muito útil aprendido em SO , aqui está uma solução:

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 função comporta-se exactamente como curl, mas irá retornar 127 (um código de retorno não utilizado por curl) no caso de um código HTTP no intervalo [400, 600[.

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

Isto enviará um pedido à url, obterá apenas a primeira linha da resposta, dividi-la-á em blocos e seleccionará a segunda.

Contém o código de resposta

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 um pedido POST, funcionaram os seguintes:

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

Use o seguinte comando cURL e canalize-o para grep assim:

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

Eis o que cada bandeira faz:

  • -I: Mostrar apenas cabeçalhos de resposta
  • -s: Silencioso - Não mostrar barra de progresso
  • -L: Siga os cabeçalhos Location:

Aqui está um link para HTTP status codes .

Execute a partir da linha de comando. Este encaracolamento corre em modo silencioso, segue qualquer redireccionamento, obtém os cabeçalhos HTTP. O grep irá imprimir o código de estado HTTP para a saída padrão.

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

Isto irá devolver a seguinte informação:

  1. dados de resposta, se algum dado for devolvido pela API como erro
  2. código de estado
4
4
4
2016-06-23 10:37:18 +0000

Aqui está um comando curl que está usando GET e que retorna o código HTTP.

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

Lembre-se que a abordagem abaixo está usando HEAD, que é mais rápido, mas pode não funcionar bem com alguns servidores HTTP menos compatíveis com a web.

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

Um exemplo de como utilizar os códigos de resposta. Utilizo-o para voltar a descarregar as bases de dados Geolite apenas se estas tiverem sido alteradas (-z) e também após redireccionamento (-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

O PO quer saber o código de estatuto. Muitas vezes quando descarrega um ficheiro, também quer ter uma ideia do seu tamanho, por isso estou a usar primeiro o curl para mostrar o código de estado e o tamanho do ficheiro e depois fechar o ficheiro verboso e directo para o local e nome que quero:

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

Depois espero pelo acabamento do curl

wait ${!}

antes de executar o próximo comando. O anterior, quando usado num script de muitos comandos como o anterior, dá uma boa resposta como:

http: 200 42824

http: 200 34728

http: 200 35452

Por favor note que -o em curl precisa de ser seguido pelo caminho completo do ficheiro + nome do ficheiro. Isto permite-lhe assim guardar os ficheiros numa estrutura de nomes sensata quando os d/l com o encaracolamento. Note também que -s e -S usados em conjunto silenciam a saída mas mostram erros. Note também que -R tenta definir o timestamp do ficheiro para o ficheiro web.

A minha resposta é baseada no que @pvandenberk sugeriu originalmente, mas além disso guarda o ficheiro algures, em vez de apenas direccionar para /dev/null.

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

Dividir o conteúdo de saída para stdout e o código de estado HTTP para stderr:

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

Se apenas for desejado o código de estado HTTP para stderr, --silent pode ser usado:

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

O fluxo desejado pode então ser escolhido redireccionando um indesejado para /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 o segundo redireccionamento se comporte como desejado, precisamos de executar o comando curl em sub-cobertura.