DEV Community

Cover image for curl, downloads, ouputs e muitos "o"s
Marcelo Andrade
Marcelo Andrade

Posted on

curl, downloads, ouputs e muitos "o"s

Todo mundo usa curl para baixar arquivos, certo?

Já aconteceu isso aqui com você?

Comando curl executando download de um binário

Essa é a primeira diferença imediata entre o curl e o wget, e pode ser irritante se você está muito acostumado com o outro.

Vamos "resolver o problema" progredindo os níveis da demanda.


Nível 0: preguiçoso

A primeira maneira para baixar arquivos é simplesmente não usar curl!

$ wget https://releases.hashicorp.com/terraform/1.2.7/terraform_1.2.7_linux_amd64.zip

$ ls
terraform_1.2.7_linux_amd64.zip
Enter fullscreen mode Exit fullscreen mode

Mas aí não aprendemos nada de novo! Próximo!


Nível 1: Júnior

A solução mais comum para este problema é usar -o especificando o nome do arquivo:

$ curl -so terraform.zip \
https://releases.hashicorp.com/terraform/1.2.7/terraform_1.2.7_linux_amd64.zip
Enter fullscreen mode Exit fullscreen mode

Comando curl com a opção - o minúsculo

Esse parâmetro é útil quando você acessa aquelas URLs todas truncadas que por acaso geram um binário para baixar, como imagem ou arquivo compactado.

Mas no exemplo acima, do Terraform, eu não precisaria especificar o nome, basta "espelhar" o "nome remoto do arquivo":

  • releases.hashicorp.com/terraform/1.2.7/terraform_1.2.7_linux_amd64.zip

E, claro, existe uma opção mais conveniente para isso.


Nível 2: pleno

A opção -O extrai o "remote file name" da URL (i.e., sem o caminho completo). É exatamente o que procuramos para este caso.

$ TD=https://releases.hashicorp.com/terraform/1.2.7
$ curl -sO $TD/terraform_1.2.7_linux_amd64.zip
Enter fullscreen mode Exit fullscreen mode

Comando curl com a opção - O maiúsculo


Muito bom, mas não precisamos parar por aqui, certo?

Ao fazer download de qualquer coisa - em especial, binários que vamos executar nos nossos preciosos sistemas operacionais -, idealmente deveríamos fazer várias verificações no download para garantir que ele é, de fato, o que queremos.

A recomendação oficial aqui seria:

  • Baixar o .zip com o Terraform;
  • Baixar o arquivo de SHA256;
  • Baixar o arquivo para verificar a assinatura do arquivo de checksum;
  • Baixar a chave gpg da Hashicorp;

Imagem do site da Hashicorp mostrando os itens descritos acima

Putz, que trabalheira! Mas ossos do ofício.

O acesso à chave da Hashicorp você pode viabilizar com o próprio GPG:

ID da chave GPG da Hashicorp

$ gpg --keyserver keyserver.ubuntu.com --recv-keys 72D7468F
gpg: key 34365D9472D7468F: public key "HashiCorp Security (hashicorp.com/security) <security@hashicorp.com>" imported
gpg: Total number processed: 1
gpg:               imported: 1

$ gpg --fingerprint 72D7468F
pub   rsa4096 2021-04-19 [SC] [expires: 2026-04-18]
      C874 011F 0AB4 0511 0D02  1055 3436 5D94 72D7 468F
uid           [ unknown] HashiCorp Security (hashicorp.com/security) <security@hashicorp.com>
Enter fullscreen mode Exit fullscreen mode

Informações batem, aparentemente estamos ok aqui.

Agora é só baixar os demais arquivos:

$ curl -sO   $TD/terraform_1.2.7_linux_amd64.zip \
             $TD/terraform_1.2.7_SHA256SUMS      \
             $TD/terraform_1.2.7_SHA256SUMS.sig
Enter fullscreen mode Exit fullscreen mode

Curl tentando baixar múltiplos arquivs com um único - O maiúsculo

Ué, o que deu errado?

Bem simples... Você não leu a documentação.

If not told otherwise, curl writes the received data to stdout. It can be instructed to instead save that data into a local file, using the --output or --remote-name options. If curl is given multiple URLs to transfer on the command line, it similarly needs multiple options for where to save them.

Múltiplas URLs são histórias diferentes, e você precisa especificar um parâmetro para cada uma delas. No exemplo em questão, precisamos de três -Os!

curl - O O O

$ curl -sOOO $TD/terraform_1.2.7_linux_amd64.zip \
             $TD/terraform_1.2.7_SHA256SUMS      \
             $TD/terraform_1.2.7_SHA256SUMS.sig
Enter fullscreen mode Exit fullscreen mode

Meio tosco né. Mas é o jeito e temos que conviver.

Ou não?


Nível 3: Sênior

Se você é daqueles que não se satisfaz com a primeira solução que encontra e não liga de perder algum tempo procurando por algo que talvez não exista, este não é o caso: o curl tem algo para você!

Você pode habilitar o --remote-name-all para resolver este assunto de maneira definitiva:

$ curl -s --remote-name-all            \
   $TD/terraform_1.2.7_linux_amd64.zip \
   $TD/terraform_1.2.7_SHA256SUMS      \
   $TD/terraform_1.2.7_SHA256SUMS.sig
Enter fullscreen mode Exit fullscreen mode

curl remote name all

O Daniel Stenberg conta a história desta opção neste blog post bem interessante sobre o histórico de opções de saída do curl. E embora a opção esteja disponível desde 2008, segundo ele mesmo, no post de 2020, ela persiste como uma das opções mais obscuras e menos usadas do curl:

Excerto do post do Daniel confirmando o parágrafo acima


Nível 4: Especialista

Apenas a título de completude, já que estamos falando sobre essas opções, vou deixar uma opção que não se encaixa no exemplo acima por utilidade.

Neste mesmo post, temos um parágrafo:

Esse parâmetro é útil quando você acessa aquelas URLs todas truncadas que por acaso geram um binário para baixar, como imagem ou arquivo compactado.

Normalmente sites que fazem isso usam cabeçalhos especiais para indicar o nome do arquivo.

Se você for na Wikipédia e tentar baixar um artigo, como, por exemplo, a seção sobre Terraforming, você será apresentado a um botão.

Esse botão é a seguinte URL:

Se você fizer uma "análise exploratória" na URL, você vai observar alguns cabeçalhos interessantes:

$ curl -sI https://en.wikipedia.org/api/rest_v1/page/pdf/Terraforming | fgrep -i content-disposition
content-disposition: attachment; filename="Terraforming.pdf"; filename*=UTF-8''Terraforming.pdf
Enter fullscreen mode Exit fullscreen mode

O nome do arquivo é indicado pelo cabeçalho de content-disposition.

Se você usar o curl com o parâmetro -J combinado com o -O, você consegue baixá-lo com o "nome certo":

$ curl -sOJ https://en.wikipedia.org/api/rest_v1/page/pdf/Terraforming
Enter fullscreen mode Exit fullscreen mode

curl - s O maiúsculo J maiúsculo


Bônus: verificação de download

Neste post, usei o download do Terraform como motivação para avaliar os parâmetros do curl. Falei sobre download seguro e até baixei a chave GPG da Hashicorp, mas não conclui... Vou colocar de bônus aqui no fim!

Baixamos os arquivos:

$ curl -s --remote-name-all \
   $TD/terraform_1.2.7_linux_amd64.zip \
   $TD/terraform_1.2.7_SHA256SUMS      \
   $TD/terraform_1.2.7_SHA256SUMS.sig
Enter fullscreen mode Exit fullscreen mode

Podemos baixar a chave de vários jeitos, e este é um deles:

$ gpg --keyserver keyserver.ubuntu.com --recv-keys 72D7468F
gpg: key 34365D9472D7468F: public key "HashiCorp Security (hashicorp.com/security) <security@hashicorp.com>" imported
gpg: Total number processed: 1
gpg:               imported: 1

$ gpg --fingerprint 72D7468F
pub   rsa4096 2021-04-19 [SC] [expires: 2026-04-18]
      C874 011F 0AB4 0511 0D02  1055 3436 5D94 72D7 468F
uid           [ unknown] HashiCorp Security (hashicorp.com/security) <security@hashicorp.com>
Enter fullscreen mode Exit fullscreen mode

Confirmo a identidade com o código do site

$ gpg --lsign-key 'C874 011F 0AB4 0511 0D02  1055 3436 5D94 72D7 468F'
Enter fullscreen mode Exit fullscreen mode

Confirmo as assinaturas do arquivo .sig do Terraform com:

$ gpg --verify terraform_1.2.7_SHA256SUMS.sig
gpg: assuming signed data in 'terraform_1.2.7_SHA256SUMS'
gpg: Signature made Wed 10 Aug 2022 02:51:41 PM -03
gpg:                using RSA key 374EC75B485913604A831CC7C820C6D5CD27AB87
gpg: checking the trustdb
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   1  signed:   1  trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: depth: 1  valid:   1  signed:   0  trust: 1-, 0q, 0n, 0m, 0f, 0u
gpg: next trustdb check due at 2024-04-06
gpg: Good signature from "HashiCorp Security (hashicorp.com/security) <security@hashicorp.com>" [full]
Enter fullscreen mode Exit fullscreen mode

Arquivo de checksums está ok! E agora o download:

$ sha256sum --ignore-missing -c terraform_1.2.7_SHA256SUMS
terraform_1.2.7_linux_amd64.zip: OK
Enter fullscreen mode Exit fullscreen mode

Pronto, pode usar o Terraform em paz!

Top comments (0)