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


799

Estou usando curlna linha de comando no Linux para emitir solicitações HTTP. Os corpos de resposta são impressos com padrão, o que é bom, mas não consigo ver na página de manual como obter curl para imprimir o código de status HTTP a partir da resposta (404, 403, etc.). Isso é possível?


Quanto a mim, posso ver no manual como obter o código de status HTTP, mas a opção -w não funciona. Eu relatei o bug para a Apple.
Nicolas Barbulesco 04/04

19
A -ibandeira, como nos curl -i https://www.example.com/, é provavelmente o que você quer, como por superuser.com/a/514798/190188
caw

Por que não apenas algo assim curl -IL http://www.example.com | grep "^HTTP\/"?
St3an 18/02

Não para o futuro: a resposta que você deseja é provavelmente de Cyril David (atualmente na 4ª posição)
WhiteHotLoveTiger

Respostas:


525

Isso deve funcionar para você se o servidor da web puder responder às solicitações HEAD (isso não será executado a GET):

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

Além disso, para permitir que o cURL siga os redirecionamentos (status 3xx), adicione -L.


155
NB: curl -Ifaz uma solicitação HTTP HEAD, o que pode ser problemático para testar o código de status HTTP para alguns servidores e serviços de aplicativos web
Jay Taylor

16
E para obter apenas o número do status, head -n 1|cut -d$' ' -f2
envie

33
Não se esqueça de redirecionar stderr de onda: curl -I http://www.example.org 2>/dev/null | head -n 1 | cut -d$' ' -f2. Adicione -L para curvar se precisar do status final após os redirecionamentos.
Aaron Blenkush

1
Seguir o redirecionamento após fazer apenas uma solicitação HEAD pode causar um comportamento interessante, dependendo de como o aplicativo está programado.
Scott McIntyre

31
curl -I -X GETenviará uma solicitação GET, mas fornecerá a mesma saída.
Jiggy #

835

Uma maneira mais específica de imprimir apenas o código de status HTTP é algo como:

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

Muito mais fácil de trabalhar em scripts, pois não requer análise :-)

O parâmetro -Ipode ser adicionado para melhorar o desempenho do carregamento de resposta. Este parâmetro apenas solicita status / cabeçalhos de resposta, sem o corpo da resposta do download.

Nota: %{http_code} retorna na primeira linha da carga útil HTTP

ou seja:

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

54
-w "% {http_code}" é o bit que imprime o código de status. Você pode adicionar uma nova linha ou dois lá para separar o código do corpo (-w "\ n \ n% {HTTP_CODE} \ n")
Jeffrey Martinez

7
Uau, essa /dev/nullcoisa ainda funciona na versão do Windows do curl que estou usando.
Uwe Keim

3
Eu acredito que isso baixa o arquivo inteiro, mesmo que tudo vá para / dev / null, portanto, não é ideal para verificar o código de status de arquivos enormes. httping -c 1 -s -G -memite um GET e não baixa o arquivo inteiro, embora eu saiba que essa pergunta é especificamente sobre curl.
RomanSt

40
FYI: -s= Não mostra o progresso do download, -o /dev/null= não exibe o corpo, -w "%{http_code}"= Escreva o código de resposta http no stdout após a saída.
Ajedi32

1
As cotações em torno de "% {http_code}" são necessárias?
Hakan Baba

217

Se você deseja ver o cabeçalho e o resultado, pode usar a opção detalhada:

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

O status 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

26
+1 para apontar o sinalizador detalhado fornece detalhes adicionais. Ótimo para testar aplicativos REST.
MrOodles

8
+1 é muito fácil de usar ao fazer uma solicitação POST (curl -v --data "...")
MegaTux 23/06

1
Ele ainda divide-os em duas saídas diferentes de arquivo (http detalhes de estado para stderr e resposta do organismo à stdout)
phil294

201

Você pode imprimir o código de status, além de todos os cabeçalhos, fazendo o seguinte:

curl -i http://example.org

O bom -ié que ele também funciona -X POST.


36
Muito melhor do que a resposta aceita (que faz uma solicitação HEAD).
N

10
Talvez óbvio, mas -ifunciona com qualquer método HTTP, não apenas GETe POST... :)
mac

3
a melhor resposta, pois faz de saída onda ambos os cabeçalhos e corpo, tornando-o adequado para a maioria das tarefas quando usado em um script
Sarge Borsch

6
Esta é a melhor resposta, e pode ser usado em conjunto com -s(não mostrar mensagens medidor de progresso ou de erro) e -S(fazer mensagens show de erro depois de tudo)
Jonathan Hartley

69

Se você deseja capturar o código de status HTTP em uma variável, mas ainda redirecionar o conteúdo para STDOUT, crie duas STDOUTs. Você pode fazer isso com a substituição do processo> () e a substituição do comando $ () .

Primeiro, crie um descritor de arquivo 3para o seu processo atual 'STDOUT with exec 3>&1.

Em seguida, use a -oopção curl para redirecionar o conteúdo da resposta para um fifo temporário usando substituição de comando e, dentro dessa substituição de comando, redirecione a saída de volta ao seu descritor de arquivo STDOUT do processo atual 3com -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')

Observe que isso não funciona /bin/shcomo o SamK observou nos comentários abaixo .


5
Isso é uma mancha séria ... e eu gosto!
spyle

3
Agora, como, por sua vez, posso redirecionar a saída para outra variável?
Roger Filmyer 12/03/2015

1
Como a saída está dentro STDOUT, você deve poder redirecionar a saída do comando para qualquer lugar que desejar, como um comando regular. Ainda não testei isso.
21815 Heath Borders

1
Não funciona com / bin / sh.
SamK 11/11

boa resposta, você também pode redirecionar para um arquivo real e cat-lo mais tarde, se você quiser portabilidade de shells
akostadinov

32

Redefinir a saída de ondulação:

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

Pode ser usado com qualquer tipo de solicitação.


-k (- inseguro) está substituindo -s (silencioso).
Ravichandra

16

SOMENTE código de status

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

Todo o crédito a este GIST


11

Essa é uma curl --faillimitação dolorosa . De man curl:

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

Mas não há como obter o código de retorno diferente de zero E o corpo da resposta no stdout.

Com base na resposta de pvandenberk e neste outro truque muito útil aprendido no SO , aqui está uma solução alternativa:

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
}

Essa função se comporta exatamente como curl, mas retornará 127 (um código de retorno não utilizado por curl) no caso de um código HTTP no intervalo [400, 600 [.


Concordado, não ser capaz de ver a saída do erro é uma limitação dolorosa da falha - muito útil. Como você pode diagnosticar uma falha da API REST sem ver a saída do erro? É tão infeliz que o bagder do mantenedor de cachos insiste teimosamente em não fornecer um erro - falha mas mostra. github.com/curl/curl/issues/1978
jamshid

Conforme declarado na documentação, ele não funciona para o código HTTP 401 e 407 :(
Logan Mzz

11

Isso enviará uma solicitação para o URL, obtenha apenas a primeira linha da resposta, divida-a em blocos e selecione a segunda.

Ele contém o código de resposta

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

1
Você pode explicar o que esse código faz e como ele resolve o problema dado pelo OP? Código inexplicável pode parecer não confiável e perigoso para os usuários.
BwDraco 16/07/2015

1
Claro, enviamos uma solicitação para url, obtemos apenas a primeira linha da resposta, dividimos em blocos e selecionamos a segunda. Ele contém o código de resposta que o OP está procurando.
Filip Spiridonov

9

Para uma solicitação POST, o seguinte funcionou:

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

Use o seguinte comando cURL e envie-o para grep da seguinte maneira:

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

Aqui está o que cada sinalizador faz:

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

Aqui está um link para os códigos de status HTTP .

Execute a partir da linha de comando. Essa onda é executada no modo silencioso, segue todos os redirecionamentos, obtém os cabeçalhos HTTP. O grep imprimirá o código de status HTTP na saída padrão.


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

Isso retornará as seguintes informações:

  1. dados de resposta, se algum dado for retornado pela API, como erro
  2. código de status

Isso não segue os redirecionamentos. Esta resposta existente é melhor superuser.com/a/442395/475508
cricket_007

Claro, você pode consultar isso também !!
srana

4

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

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

Lembre-se de que a abordagem abaixo está sendo usada HEAD, que é mais rápida, mas pode não funcionar bem com alguns servidores HTTP menos compatíveis com a Web.

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

Não está funcionando no OS X pelo menos.
Ain

Funcionando bem para mim no OS X High Sierra 10.13.6.
Ben Baron

4

Um exemplo de como usar os códigos de resposta. Eu uso isso para baixar novamente os bancos de dados Geolite apenas se eles foram alterados ( -z) e também após redirecionamentos ( -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

O OP quer saber o código de status. Freqüentemente, ao baixar um arquivo, você também quer ter uma ideia do seu tamanho, então estou usando o curl primeiro para mostrar o código de status e o tamanho do arquivo e, em seguida, desative o arquivo detalhado e direto para o local e o nome que desejo:

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

Então eu espero pelo acabamento do cacho

wait ${!}

antes de executar o próximo comando. O exemplo acima, quando usado em um script de muitos comandos como o acima, fornece uma boa resposta, como:

http: 200 42824

http: 200 34728

http: 200 35452

Observe que -o in curl precisa ser seguido pelo caminho completo do arquivo + nome do arquivo. Dessa forma, você pode salvar arquivos em uma estrutura de nome sensível quando você os desativa com curvatura. Observe também que -s e -S usados ​​juntos silenciam a saída, mas mostram erros. Observe também que -R tenta definir o registro de data e hora do arquivo para o arquivo da web.

Minha resposta é baseada no que o @pvandenberk sugeriu originalmente, mas além disso, ele salva o arquivo em algum lugar, em vez de apenas direcionar para / dev / null.


1

Divida o conteúdo de saída stdoute o código de status HTTP para stderr:

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

Se apenas o código de status HTTP for desejado para stderr, --silentpoderá ser usado:

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

O fluxo desejado pode ser escolhido redirecionando o 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>
...

Observe que, para o segundo redirecionamento se comportar conforme desejado, precisamos executar o comando curl no subshell.


1
Requer bashsubstituição de processo.
Jaakko

@Bruno, mudei o exemplo de superuser.com/revisions/1444693/2 , pois acho que os /tmp/out /tmp/errarquivos podem causar resultados inesperados se forem executados em paralelo.
Jaakko
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.