Baixar e descompactar arquivos ZIP, tar.gz e gzip com cURL
Encadeie o cURL com tar ou gzip por meio de um pipe para descompactar um download à medida
que ele chega. Para arquivos ZIP, baixe primeiro para um arquivo temporário e depois execute
unzip. Os exemplos abaixo verificam tanto o download quanto a extração e se recusam a
reutilizar um diretório de saída existente.
Comandos básicos do cURL para download
Use Bash no Linux, cURL, GNU tar, GNU gzip, Info-ZIP UnZip e os utilitários padrão mkdir,
mktemp e rm. Os comandos foram testados no Ubuntu 24.04 com Bash 5.2, cURL 8.5.0, GNU tar
1.35, gzip 1.12 e UnZip 6.00. Eles não são comandos do PowerShell nem comandos sh genéricos.
Escolha o bloco do seu formato e substitua a URL https://example.com/… por uma URL de download confiável.
Execute o bloco completo, incluindo os parênteses, no Bash, a partir de um diretório que pertença a
você e no qual você tenha permissão de escrita. Cada bloco é independente. Você também pode salvar
um deles como extract.sh e executar bash extract.sh.
As opções do cURL usadas aqui são:
-f: Retorna um erro em falhas HTTP, como 404, sem repassar a página de erro ao extrator.-sS: Oculta o medidor de progresso, mas continua exibindo os erros.-L: Segue redirecionamentos.-o: Grava o download no arquivo especificado em vez da saída padrão.
O diretório de saída não pode existir, mesmo que esteja vazio. mkdir o reserva antes que
qualquer download comece; não altere esse comando para mkdir -p. O trap de limpeza só é instalado
depois que a criação é bem-sucedida, então um comando repetido deixa o resultado anterior intacto.
umask 077 torna os diretórios de trabalho recém-criados privados para o seu usuário, embora as
entradas do arquivo compactado possam trazer seus próprios modos.
Como lidar com diferentes formatos de arquivo compactado
Arquivos Zip (.zip)
O Info-ZIP UnZip 6.0 não lê um arquivo compactado a partir da stdin. A opção -p dele envia os
arquivos extraídos para a stdout; ela não aceita um pipe de ZIP como entrada. O
manual do UnZip documenta essa limitação. Use um arquivo baixado comum para que o
extrator possa se posicionar livremente dentro dele.
(
umask 077
dest='./zip-output'
mkdir -- "$dest" || exit
trap 'rm -rf -- "$dest"' EXIT
work=$(mktemp -d) || exit
trap 'rm -rf -- "$work" "$dest"' EXIT
curl -fsSL 'https://example.com/archive.zip' -o "$work/archive.zip" || exit
unzip -q "$work/archive.zip" -d "$dest" </dev/null || exit
rm -rf -- "$work" || exit
trap - EXIT
printf 'Extracted to %s\n' "$dest"
)
Em caso de sucesso, os arquivos ficam em ./zip-output/, com a estrutura de diretórios do arquivo
compactado intacta.
mktemp -d cria um diretório temporário exclusivo em $TMPDIR, ou em /tmp quando ele não está
definido. Somente essa cópia privada de archive.zip é removida. Um arquivo chamado temp.zip no seu
diretório atual nunca é usado. Este exemplo é para arquivos ZIP não criptografados; fechar a stdin
impede que um prompt interativo de entrada trave o comando.
Arquivos tar com gzip (.tar.gz ou .tgz)
Um arquivo tar compactado com gzip pode ser transmitido diretamente para o GNU tar:
(
set -o pipefail
umask 077
dest='./tar-output'
mkdir -- "$dest" || exit
trap 'rm -rf -- "$dest"' EXIT
curl -fsSL 'https://example.com/archive.tar.gz' | tar -xzf - -C "$dest" || exit
trap - EXIT
printf 'Extracted to %s\n' "$dest"
)
Aqui, -x extrai, -z descompacta o gzip, -f - lê o arquivo compactado da stdin e
-C escolhe o diretório de extração. Os arquivos vão para ./tar-output/; nenhum arquivo
compactado é salvo. Se o arquivo compactado contiver um diretório de nível superior, esse diretório
permanece dentro de tar-output.
A opção pipefail do Bash faz o pipeline falhar quando o cURL ou o tar
falha. Sem ela, um extrator bem-sucedido pode ocultar uma transferência com falha, mesmo uma que
informe um erro depois de entregar bytes utilizáveis do arquivo compactado. O || exit
retorna o status de falha do subshell e dispara a limpeza. Os parênteses impedem que essas
configurações do shell e as chamadas de exit afetem sua sessão interativa.
Arquivos gzip (.gz)
O gzip simples compacta um fluxo de bytes; ele não fornece uma árvore de diretórios. Escolha
explicitamente o nome do arquivo de saída com gzip -dc e um redirecionamento:
(
set -o pipefail
umask 077
dest='./gzip-output'
mkdir -- "$dest" || exit
trap 'rm -rf -- "$dest"' EXIT
curl -fsSL 'https://example.com/file.gz' | gzip -dc > "$dest/payload" || exit
trap - EXIT
printf 'Decompressed to %s/payload\n' "$dest"
)
-d descompacta e -c grava na stdout. O resultado é ./gzip-output/payload, inclusive quando o
arquivo original está vazio ou contém dados binários. O diretório que o envolve impede que o
redirecionamento trunque um resultado anterior. Se um arquivo chamado .gz na verdade contiver
um arquivo tar, use o exemplo do tar com essa URL para extrair os membros dele.
Considerações de segurança
Use estes comandos para arquivos compactados de uma fonte em que você confia, com o seu usuário
normal. O diretório novo protege a saída existente contra reutilização acidental; ele não é uma
sandbox. Caminhos, links e permissões do arquivo compactado, vulnerabilidades do extrator e um
tamanho expandido excessivo continuam sendo riscos relevantes. As
orientações de segurança do GNU tar explicam os riscos de extrair arquivos
compactados não confiáveis. --strip-components altera o layout dos caminhos; ele não torna seguro um
arquivo compactado arbitrário.
O streaming começa a gravar arquivos antes de a transferência terminar. Aguarde um status de saída zero e a mensagem de sucesso antes de usá-los. Em caso de erro no download ou na extração, o trap remove o diretório de saída recém-criado. Um encerramento forçado ou um erro de permissão durante a limpeza pode deixar arquivos parciais para trás; inspecione esse diretório antes de escolher um novo destino para uma nova tentativa.
Armadilhas comuns e dicas de solução de problemas
- O destino já existe: Escolha um novo nome para
dest. O comando falha deliberadamente antes do download, preservando o diretório, o arquivo ou o link simbólico existente. - O cURL informa um erro de HTTP ou de conexão: Verifique a URL de download e os requisitos de acesso. Uma página web que retorna HTTP 200 ainda assim não é um arquivo compactado; o extrator também precisa aceitar o conteúdo baixado.
- O extrator informa EOF inesperado, erro de checksum ou formato inválido: Considere que o
resultado falhou. Confirme o formato e obtenha uma cópia completa com o publicador. Um sufixo
.gz, por si só, não indica se o conteúdo é um arquivo tar. - Uma transferência continua falhando: Execute o bloco inteiro novamente depois de resolver a causa. Não se limite a adicionar flags de nova tentativa a um pipe: o cURL não consegue recolher bytes já enviados adiante. A documentação sobre novas tentativas do cURL alerta que uma saída redirecionada pode receber dados duplicados.
- A extração fica sem espaço: Reserve espaço para os arquivos expandidos. O exemplo de ZIP também precisa de espaço para o arquivo compactado baixado no diretório temporário.
Decida quando salvar o arquivo compactado
O streaming de tar.gz e gzip economiza o espaço em disco que o download compactado ocuparia. Se você precisar comparar o checksum de um publicador ou verificar uma assinatura antes de extrair, baixe primeiro para um diretório de trabalho novo e verifique esse arquivo. O fato de um extrator aceitar o arquivo compactado estabelece que ele conseguiu lê-lo; não estabelece quem o publicou.
