Comando curl: uso de opções, requisições POST e download de arquivos
O comando curl é uma ferramenta que envia uma requisição a um endereço web pelo terminal e mostra a resposta exatamente como veio. Com uma única linha, você confere o corpo da página, os cabeçalhos e o código de status. Ao enviar requisições curl de um servidor AlmaLinux 9 para um site WordPress, o endereço http respondeu com um 301 indicando o endereço https, e uma requisição à REST API sem autenticação foi recusada com 401.
1️⃣ Uso básico do comando curl e o corpo da resposta
Se você colocar um endereço depois de curl, ele envia uma requisição GET para esse endereço e mostra na tela o corpo da resposta. Ao pedir o robots.txt que o WordPress gera, o conteúdo do arquivo de três linhas veio exatamente como está.
curl https://example.com/robots.txtUser-agent: *
Disallow: /wp-admin/
Allow: /wp-admin/admin-ajax.phpÉ fácil esperar a mesma página que você vê ao digitar o endereço no navegador, mas o que o curl mostra é o HTML bruto que o servidor enviou. O curl não executa scripts nem pede imagens e CSS separadamente. O HTML de uma página é longo, então, para endereços de páginas web, passamos a saída para o head por um pipe e conferimos só as primeiras linhas.
curl -s https://example.com/ | head -n 2<!DOCTYPE html>
<html lang="ko-KR">Com -s, o indicador de progresso que se mistura à tela quando a saída passa por um pipe fica oculto. O HTML recebido só do endereço da página inicial tinha 96.679 bytes. Arquivos de imagem e de script não entram nesse tamanho.
2️⃣ Conferir cabeçalhos com curl -I e seguir redirecionamentos com -L
Só pelo corpo não dá para saber se a requisição deu certo, então você confere o código de status e os cabeçalhos separadamente com -I. O -I envia uma requisição HEAD e mostra só os cabeçalhos da resposta, sem o corpo. É como conferir a etiqueta de envio sem abrir a caixa.
curl -I https://example.com/HTTP/2 200
server: nginx/1.28.0
date: Wed, 28 Oct 2026 05:29:23 GMT
content-type: text/html; charset=UTF-8
vary: Accept-Encoding
last-modified: Tue, 27 Oct 2026 21:12:18 GMT
cache-control: max-age=0
expires: Wed, 28 Oct 2026 05:29:23 GMT
accept-ranges: none
alt-svc: h3=":443"; ma=86400O [HTTP/2 200] da primeira linha é o código de status. Abaixo vêm o tipo de servidor, o tipo de conteúdo e os cabeçalhos de cache. Se você enviar a mesma requisição ao endereço http, aparece um 301 junto com o endereço https de destino no cabeçalho [Location].
curl -I http://example.com/HTTP/1.1 301 Moved Permanently
Server: nginx/1.28.0
Date: Wed, 28 Oct 2026 05:27:51 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://example.com/Ao pedir o endereço http sem opções, o curl não fez nova requisição ao endereço de [Location]: mostrou só as 7 linhas do corpo da resposta 301 e terminou.
curl http://example.com/<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.28.0</center>
</body>
</html>Com -L, o curl faz nova requisição ao endereço de [Location]. Combinando com -I e executando -IL, os cabeçalhos da resposta 301 são seguidos, em ordem, pelos da resposta 200.
curl -IL http://example.com/HTTP/1.1 301 Moved Permanently
Server: nginx/1.28.0
Date: Wed, 28 Oct 2026 05:29:23 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://example.com/
HTTP/2 200
server: nginx/1.28.0
date: Wed, 28 Oct 2026 05:29:23 GMT
content-type: text/html; charset=UTF-8
vary: Accept-Encoding
last-modified: Tue, 27 Oct 2026 21:12:18 GMT
cache-control: max-age=0
expires: Wed, 28 Oct 2026 05:29:23 GMT
accept-ranges: none
alt-svc: h3=":443"; ma=86400No diagrama abaixo, você compara passo a passo quantas requisições saem e o que aparece na tela conforme a opção.
3️⃣ Baixar arquivos com o comando curl (-o, -O)
O -O salva o arquivo na pasta atual com o último nome de arquivo do endereço. Enquanto salva, a tela mostra o indicador de progresso em vez do corpo.
curl -O https://example.com/wp-includes/images/w-logo-blue.png % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 3113 100 3113 0 0 178k 0 --:--:-- --:--:-- --:--:-- 190kls -l w-logo-blue.png-rw-r--r-- 1 root root 3113 Oct 28 14:29 w-logo-blue.pngDepois do download, [Total] e [Received] no indicador de progresso marcavam 3113, e o tamanho do arquivo conferido com ls -l também bateu: 3.113 bytes.
Para escolher você mesmo o nome do arquivo, escreva-o depois de -o. Abaixo está o resultado de salvar o endereço da página inicial como home.html.
curl -o home.html https://example.com/ % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 96679 0 96679 0 0 4291k 0 --:--:-- --:--:-- --:--:-- 4291kls -l home.html-rw-r--r-- 1 root root 96679 Oct 28 14:29 home.htmlO -O usa o nome de arquivo do fim do endereço exatamente como está, por isso não serve para endereços de páginas que terminam em barra. Se você adicionar -O ao endereço da página inicial, o curl não encontra um nome de arquivo e termina com o erro abaixo.
curl -O https://example.com/curl: Remote file name has no length!
curl: (23) Failed writing received data to disk/application4️⃣ Requisições POST com curl e envio de dados JSON
Para enviar dados em uma requisição que até agora só lia, use -d, e adicione -H para indicar o formato dos dados. O -d envia como corpo POST os dados que você escrever depois dele. Sem outra indicação, o [Content-Type] é [application/x-www-form-urlencoded].
Com -d, o método da requisição passa a ser POST, então você pode omitir [-X POST]. A documentação oficial também explica que normalmente o -X não é necessário.
Para enviar JSON, mude o [Content-Type] para [application/json] com -H. Abaixo está o resultado de enviar à REST API do WordPress uma requisição de criação de post sem autenticação.
curl -s -X POST -H 'Content-Type: application/json' -d '{"title":"curl test"}' https://example.com/wp-json/wp/v2/posts{"code":"rest_authentication_error","message":"\uc8c4\uc1a1\ud569\ub2c8\ub2e4. REST API \uc694\uccad\uc744 \ud560 \uc218 \uc788\ub294 \uad8c\ud55c\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.","data":{"status":401}}O site para o qual enviamos a requisição bloqueia requisições à REST API de usuários que não fizeram login e por isso code retornou [rest_authentication_error], com status 401. Pela mesma configuração, pedir com GET a lista de posts no mesmo endereço também retornou 401. O valor de message é uma frase de erro escrita no idioma do site e convertida para a notação Unicode do JSON.
Para ver só o código de status, descarte o corpo com [-o /dev/null] e mostre só o http_code com -w.
curl -s -o /dev/null -w '%{http_code}\n' -X POST -H 'Content-Type: application/json' -d '{"title":"curl test"}' https://example.com/wp-json/wp/v2/posts4015️⃣ Medir o tempo de resposta com o comando curl (-w)
Quando uma resposta está lenta, é fácil olhar só o total, mas para saber se o tempo foi gasto na conexão ou no processamento do servidor é preciso mostrar separadamente o tempo de cada etapa. O -w mostra os valores medidos no formato que você indicar quando a requisição termina. Os valores preenchem os espaços [%{nome da variável}] do formato.
Descarte o corpo com [-o /dev/null] e oculte o indicador de progresso com -s.
curl -o /dev/null -s -w 'code: %{http_code}\nconnect: %{time_connect}\ntls: %{time_appconnect}\nttfb: %{time_starttransfer}\ntotal: %{time_total}\n' https://example.com/code: 200
connect: 0.001507
tls: 0.017728
ttfb: 0.021912
total: 0.022825connect é a conexão TCP, tls a negociação TLS, ttfb o tempo até pouco antes do envio do primeiro byte e total o tempo até o fim da transferência. Os quatro valores são segundos acumulados desde o início da requisição.
Como o servidor que executava o curl e o site que recebia a requisição estavam no mesmo servidor, a conexão levou só 0,0015 segundo; a negociação TLS terminou em 0,0177 segundo e o primeiro byte chegou em 0,0219 segundo. Do fim da negociação TLS até a chegada do primeiro byte passaram cerca de 0,004 segundo. A documentação oficial explica que essa etapa inclui o tempo que o servidor leva para gerar o resultado.
Ao executar o mesmo comando mais três vezes, o total ficou entre 0,0219 e 0,0226 segundo.
🔲 Simulador do comando curl
No simulador abaixo, você pode digitar os comandos vistos até aqui e conferir como a saída muda com cada opção.
🔢 FAQ & conteúdo recomendado








ℹ️ Aviso de afiliados
O conteúdo deste site contém links de afiliados. Quando um visitante compra um produto ou serviço por meio de um desses links, o site recebe uma comissão do vendedor. O valor que o comprador paga (em promoções, ele diminui ↓) não aumenta por causa disso. Preços, descontos e informações de estoque valem para o momento em que o texto foi escrito e podem ter mudado, por isso confirme com o vendedor antes de comprar. Os produtos são escolhidos e avaliados por critérios próprios, e o recebimento de comissão não influencia a ordem de apresentação nem o conteúdo das avaliações.