Eu quero criar um .tgz a partir do conteúdo de um diretório. Eu também quero remover o " ./
" inicial do conteúdo com tar.
Eu tinha feito isso da seguinte forma:
cd /path/to/files/ && find . -type f | cut -c 3- | xargs czf /path/to/tgz/myTgz.tgz
Aprendi recentemente que usar xargs
pode não ser a melhor maneira de fazer isso porque xargs
pode invocar tar
várias vezes se a lista cmdline arg ficar muito longa, e fui aconselhado a usar tar
a capacidade de ler uma lista de arquivos de entrada de stdin. Acabei encontrando este artigo sobre como fazer isso. No entanto, acho que a recomendação ...
cd /path/to/files/ && find . -type f | cut -c 3- | tar czf foo.tgz -T -
... parece não ser portátil. Ele funciona bem no meu dev PC, mas em um destino do busybox, recebo o seguinte erro ao executar o mesmo comando:
tar: can't open '-': No such file or directory
Então, minha pergunta : existe uma maneira verdadeiramente portátil / global de invocar tar
para criar um .tgz
alimentando arquivos de entrada de stdin (em oposição aos argumentos cmdline)?
(Não é uma opção disponível para mim instalar alternativas tar
como gnutar
/ bsdtar
/etc.)
(Pergunta secundária: Por que o -T -
argumento " " para tar
denotar " lê arquivos destdin
"? Na tar
página man, tudo o que pude encontrar foi que " -T
" significa:
obter nomes para extrair ou criar de FILE
... mas não consegui ver nenhuma referência a um simples " -
")
É uma convenção comum interpretar
-
para significar entrada padrão onde um nome de arquivo de entrada é esperado e significar saída padrão onde um nome de arquivo de saída é esperado. Como esta é uma convenção comum, o breve resumo de ajuda na página de manual do GNU tar não a menciona, mas o manual completo (geralmente disponível localmente através deinfo tar
) sim. As diretrizes de sintaxe do utilitário de linha de comando POSIX incluem essa convenção, por isso é bastante difundida (mas é sempre uma escolha por parte do autor do programa).Os utilitários BusyBox seguem esta convenção. Mas o manual não menciona
tar
como suporte a opção-T
, e nem a versão na máquina que estou postando isso (1.27.2 no Ubuntu). Não sei por que você está recebendo o erro “: Nenhum arquivo ou diretório” em vez de “opção inválida -- 'T'”. Parece que seutar
interpreta-T
como uma opção que não recebe um argumento, então vê-
como um nome de arquivo. Como neste contexto o tar precisa de um nome de arquivo para colocar no arquivo, e não apenas algum conteúdo que vem de um arquivo, não faria sentido usar a interpretação stdin/stdout para-
.Os utilitários BusyBox suportam um conjunto restrito de funcionalidades por design, porque são destinados a sistemas embarcados onde os recursos mais sofisticados dos utilitários GNU não se encaixam. Aparentemente
-T
não é um recurso que os designers do BusyBox consideraram útil.Eu não acho que o tar BusyBox tenha alguma maneira de ler nomes de arquivos de stdin. Se você precisar arquivar um subconjunto dos arquivos em um diretório e não precisar de nenhum link simbólico no arquivo, uma solução alternativa é criar uma floresta de links simbólicos em um diretório temporário e arquivar esse diretório temporário.
Não está claro exatamente por que você está usando
find
. Se você deseja apenas os arquivos no diretório atual, por que nãotar czf /path/to/archive.tgz -- *
? Seu comando faz sentido se houver subdiretórios e você quiser arquivar os arquivos nesses subdiretórios, mas não os próprios diretórios (presumivelmente para restaurá-los em um local onde a estrutura de diretórios deve existir, mas pode ter permissões diferentes). Neste caso, uma liderança./
não faria mal algum.Eu sei que é uma resposta estúpida e talvez não seja boa para você, mas quão ruim é se você apenas...
Você pode usar a
-u/--update
opção em conjunto comxargs
. Eu apenas tentei e para provar que funciona, dei os argumentos do nome do arquivo paratar
um por um usandoxargs -n 1
:find top_of_tree/ -type f | xargs -n 1 tar -uf archive.tar
Claro, isso é apenas uma prova de conceito. No seu caso, provavelmente é mais prático permitir
xargs
separar a lista de argumentos em partes maiores que não excedam o limite de comprimento do argumento, para evitar muitas chamadas paratar
:find top_of_tree/ -type f | xargs tar -uf archive.tar
O pré-requisito é que todas as implementações de
tar
em suas plataformas suportem pelo menos um dos-u/--update
sinalizadores.EDIT: os
-u/--update
sinalizadores permitemtar
criar e anexar a um arquivo.Acabei de notar que, infelizmente, você não pode atualizar arquivos compactados (tgz, criados com o
-c
sinalizador). No entanto, você pode criar um arquivo não compactado primeiro e depois compactar os resultados.Além disso, não deve confundir você que estou usando sinalizadores para
tar
com um hífen (caractere '-'). Aceita as duas formas. No meu exemplo,-uf
seria equivalente aouf
seu.Quanto à
-
opção, ela provavelmente não está documentada na página man dotar
porque é uma convenção Unix muito comum para ferramentas de linha de comando que lidam com fluxos e arquivos nomeados.-
geralmente é um argumento especial para filtros e nomeia o fluxo de entrada padrão como um arquivo.