Por que a extração desse tgz está causando um erro no meu Mac, mas não no Linux?

27

Estou com um problema bastante estranho e não consigo descobrir o que está acontecendo. Eu tenho um arquivo tgz, scip-3.2.0.tgz , que está lançando um erro quando tento descompactá-lo. O erro está ocorrendo apenas no OS X (eu estou no 10.10.4). Posso extrair o arquivo sem erro em uma caixa Linux executando o CentOS 6.6. O erro ocorre ao usar o comando da linha de tarcomandos e ao usar o utilitário de arquivamento. Enviei por email a lista de discussão SCIP e tenho o mesmo hash SHA-1 que outro usuário ( e085a4a3591eddf945dcb365d97d2512c267e374), portanto, não houve um erro de download. Eles não têm certeza do que está acontecendo.

Aqui está o erro que recebo ao tentar descompactar usando o utilitário de arquivamento:

erro no utilitário de arquivamento

Caso a imagem se quebre, o texto na imagem diz o seguinte:

Não foi possível expandir "scip-3.2.0.tgz" para "Área de trabalho".
(Erro 1 - Operação não permitida.)

E quando tento descompactar via linha de comando, essa é a saída que recebo . É a última linha ( tar: Error exit delayed from previous errors.) que me preocupa. Não vejo o que está causando isso. O arquivo parece extraído sem problemas, mas não confio nele com esse erro.

Alguém sabe o que está causando isso?

[edit]
Olhando um pouco mais de perto a saída, a linha 1108 contém o erro:

x scip-3.2.0/applications/Coloring/Makefile: Can't create 'scip-3.2.0/applications/Coloring/Makefile'
Geoff
fonte
2
Funciona com outro aplicativo como o desarquivador? wakaba.c3.cx/s/apps/unarchiver.html
TryTryAgain
Sim! Eu me pergunto o que eles estão fazendo de maneira diferente. Parte do problema é que eu tenho um script bash que automatiza um monte de coisas, e uma das coisas que ele precisa fazer é extrair esse tgz para que ele possa construir o que está dentro dele. Gostaria de saber se há um erro no tarcomando que vem com o OS X.
Geoff
1
Muito possivelmente, há um erro. Eu achei o utilitário de arquivamento do OS X embutido bastante ruim. Não há como você arquivar novamente os arquivos necessários em um zip ou algo assim? Além disso, se você estiver criando um script, o erro também ocorre quando você gunzip -c scip-3.2.0.tgz | tar xopf -na linha de comando, como o usaria para o seu script?
TryTryAgain
Sim, esse comando lança o mesmo erro. gunzipfunciona muito bem, mas quando tento extrair o tarball descompactado, é quando o erro é gerado.
Geoff
Ah, acontece que houve de fato um erro no tarball! Eu não sou louco. Vou escrever uma resposta mais detalhada. Aparentemente, o utilitário tar no OS X foi o correto aqui!
Geoff

Respostas:

32

Isso deve ajudar a identificar o que está acontecendo na resposta de Johnny , bem como responder à pergunta de por que isso funciona no Linux, mas não no Mac.

O problema está no fato de o Mac OS X usar bsdtar, enquanto a maioria dos sistemas Linux usa gnutar.

Você pode instalar gnutarem um Mac com Homebrew, usando brew install gnu-tar, que vai ligar simbolicamente gnutarem /usr/local/bincomo gtar.

Se você instalar gnutar, poderá reproduzir o problema seguindo as etapas na resposta de Johnny .

$ brew install gnu-tar
==> Downloading https://homebrew.bintray.com/bottles/gnu-tar-1.28.yosemite.bottle.2.tar.gz
######################################################################## 100.0%
==> Pouring gnu-tar-1.28.yosemite.bottle.2.tar.gz
==> Caveats
gnu-tar has been installed as "gtar".

If you really need to use it as "tar", you can add a "gnubin" directory
to your PATH from your bashrc like:

    PATH="/usr/local/opt/gnu-tar/libexec/gnubin:$PATH"
==> Summary
🍺  /usr/local/Cellar/gnu-tar/1.28: 13 files, 1.6M
$ mkdir test
$ touch test/a test/b
$ gtar -zcvf test.tar.gz test test/a # make the archive with gnutar
test/
test/a
test/b
test/a
$ gtar -ztvf test.tar.gz
drwxr-xr-x adamliter/staff   0 2015-07-28 22:41 test/
-rw-r--r-- adamliter/staff   0 2015-07-28 22:41 test/a
-rw-r--r-- adamliter/staff   0 2015-07-28 22:41 test/b
hrw-r--r-- adamliter/staff   0 2015-07-28 22:41 test/a link to test/a
$ rm -r test
$ tar -xvf test.tar.gz # try to unpack the archive with bsdtar
x test/
x test/a
x test/b
x test/a: Can't create 'test/a'
tar: Error exit delayed from previous errors.
$ echo $?
1

Então, obviamente, gnutararquiva as coisas de maneira diferente, de maneira que causa bsdtarengasgos com duplicatas. O fato de gtar -ztvf test.tar.gzindicar que a segunda instância test/aé arquivada como a link to test/aé relevante. Como Johnny aponta nos comentários, gnutarele armazenará duplicatas como links físicos em vez do arquivo real, que pode ser desativado --hard-dereference.

Ou seja, você pode fazer o seguinte:

$ mkdir test
$ touch test/a test/b
$ gtar -zcvf test.tar.gz test test/a --hard-dereference
test/
test/a
test/b
test/a
$ gtar -ztvf test.tar.gz test
drwxr-xr-x adamliter/staff   0 2015-07-28 23:49 test/
-rw-r--r-- adamliter/staff   0 2015-07-28 23:49 test/a
-rw-r--r-- adamliter/staff   0 2015-07-28 23:49 test/b
-rw-r--r-- adamliter/staff   0 2015-07-28 23:49 test/a # note that this is no longer a link
$ rm -r test
$ tar -xvf test.tar.gz # unpack with bsdtar
x test/
x test/a
x test/b
x test/a
$ echo $?
0
$ ls test/
a b

No entanto, nesse caso, você obviamente não controla a criação do tarball, portanto --hard-dereferencenão é uma opção. Felizmente, com base na resposta do OP , parece que esse problema foi corrigido pelo montante.

No entanto, se alguém mais enfrentar esse problema no futuro e precisar de uma solução rápida ou tiver um mantenedor upstream que não responda, há uma solução alternativa.

Depois de identificar qual é o arquivo duplicado, você pode usar a --fast-readopção de bsdtar(observe que essa opção é apenas parte dela bsdtar, não gnutar ):

 -q (--fast-read)
         (x and t mode only) Extract or list only the first archive entry that matches each pattern or filename operand.  Exit as soon as each specified pat-
         tern or filename has been matched.  By default, the archive is always read to the very end, since there can be multiple entries with the same name
         and, by convention, later entries overwrite earlier entries.  This option is provided as a performance optimization.

Portanto, no exemplo de brinquedo que eu criei após o exemplo de brinquedo na resposta de Johnny , o arquivo duplicado é test/a. Portanto, você pode evitar esse problema fazendo o seguinte:

# this set of commands picks up from the first set of commands
# i.e., the following assumes a tarball that was *not* made with
# the --hard-dereference option, although this will work just as well
# with one that was
$ tar -xvqf test.tar.gz test/a # unarchive the first instance of test/a
x test/a
$ tar -xvf test.tar.gz --exclude test/a # unarchive everything except test/a
x test/
x test/b
$ echo $?
0
$ ls test/
a b

Além disso, gnutaré perfeitamente feliz descompactar um arquivo com duplicatas criadas por si só, mesmo quando a --hard-dereferenceopção não foi usada:

$ rm -r test
$ gtar -xvf test.tar.gz
test/
test/a
test/b
test/a
$ echo $?
0
$ ls test/
a b

Portanto, isso responde à sua pergunta de por que um erro é gerado no Mac, mas não no Linux. (A maioria) das distribuições Linux são fornecidas e gnutar, como o pacote foi presumivelmente empacotado gnutar, não haverá erro ao descompactar gnutar, mas haverá um erro ao descompactar bsdtar.


Para leituras e referências adicionais, pode-se considerar quais são as diferenças entre o bsdtar e o GNU tar? no Unix.SE.

Adam Liter
fonte
Uau, boa investigação, eu não fazia ideia de que havia alguma diferença significativa entre gnutar e bsd tar. Com base no seu gtar -tcvf, o gnutar é "inteligente" o suficiente para otimizar o segundo arquivo de cópia como um link, em vez de duplicá-lo no arquivo.
Johnny
Depois de vasculhar os documentos, parece que esse é um efeito colateral do manuseio de links físicos do gtar. Parece pensar que o arquivo duplicado é realmente um link físico para o arquivo; portanto, ele é armazenado como um link em vez do arquivo real. Dar a gtar a --hard-dereferenceopção desativa esse comportamento.
Johnny
@ Johnny Foram realmente dois dos mantenedores da Homebrew que descobriram isso (Misty De Meo e Dominyk Tiller). Um mantenedor de algum software que eu uso lançou uma nova versão com um arquivo duplicado no tarball, o que causou problemas ao tentar instalar a nova versão com o Homebrew (obviamente). De qualquer forma, obrigado por conferir os documentos! Vou acrescentar isso à resposta.
Adam Liter
Isto e excelente. Estou marcando esta como a resposta, já que é a explicação mais completa do que está acontecendo. Obrigado!
Geoff
7

A existência de um arquivo duplicado no arquivo morto não deve torná-lo inválido ou incapaz de ser extraído no OSX, pois, por padrão, o tar substitui as duplicatas.

Então, eu estou um pouco confuso com o comportamento na sua Síntese - OSX tar permite por arquivos duplicados em um arquivo (um retrocesso para seu propósito original como um t macaco ar cebolinha utilidade, por isso permite que arquivos sejam anexados ao final de o arquivo de fita e, quando o arquivo for restaurado, a versão mais recente do arquivo substituirá a (s) versão (ões) mais antiga (s)

É somente quando a opção "-k" está presente que o tar deve avisar sobre arquivos preexistentes.

Aqui, criei um arquivo com um arquivo duplicado e o extraí sem problemas. Não foi até eu adicionar a opção -k que me avisou sobre o arquivo duplicado:

Macbook> tar --version
bsdtar 2.8.3 - libarchive 2.8.3
Macbook> mkdir test
Macbook> touch test/a test/b
Macbook> tar -zcvf test.tar.gz test test/a
a test
a test/a
a test/b
a test/a
Macbook> tar -ztvf test.tar.gz
drwxr-xr-x  0 user group       0 Jul 28 10:42 test/
-rw-r--r--  0 user group       0 Jul 28 10:42 test/a
-rw-r--r--  0 user group       0 Jul 28 10:42 test/b
-rw-r--r--  0 user group       0 Jul 28 10:42 test/a
Macbook> rm -r test
Macbook> tar -xvf test.tar.gz
x test/
x test/a
x test/b
x test/a
Macbook> echo $?
0
Macbook> rm -r test
Macbook> tar -k -xvf test.tar.gz
x test/
x test/a
x test/b
x test/a: Already exists
tar: Error exit delayed from previous errors.
Macbook> echo $?
1

Um problema simples de umask também não parece ser o culpado, tentei alterar meu umask para 0777 e ainda posso extrair o arquivo:

Macbook> tar -xvf test.tar
x test/
x test/a
x test/b
x test/a
Macbook> ls -l test
ls: test: Permission denied
Macbook> sudo ls -l test
total 0
----------  1 someuser  wheel  0 Jul 28 13:48 a
----------  1 someuser  wheel  0 Jul 28 13:48 b

Eu pensei que poderia duplicar o problema anexando deliberadamente um diretório não gravável ao arquivo, mas isso não funcionou, o tar não atualizou as permissões no diretório quando extraiu o arquivo:

Macbook> mkdir -p testdir1/test testdir2/test
Macbook> touch testdir1/test/{a,b} testdir2/test/a
Macbook> chmod -w testdir2/test
Macbook> touch testdir2/test/b
touch: testdir2/test/b: Permission denied
Macbook> find testdir* -ls  | awk '{print $3, $11}'
drwxrwx--- testdir1
drwxrwx--- testdir1/test
-rw-rw---- testdir1/test/a
-rw-rw---- testdir1/test/b
drwxrwx--- testdir2
dr-xr-x--- testdir2/test
-rw-rw---- testdir2/test/a
Macbook> cd testdir1
Macbook> tar -cvf ../test.tar test/*
a test/a
a test/b
Macbook> cd ../testdir2
Macbook> tar -rvf ../test.tar test
a test
a test/a
Macbook> cd ..
Macbook> tar -tvf ./test.tar
-rw-rw----  0 username groupname       0 Jul 28 15:40 test/a
-rw-rw----  0 username groupname       0 Jul 28 15:40 test/b
-rw-rw----  0 username groupname       0 Jul 28 15:40 test/a
dr-xr-x---  0 username groupname       0 Jul 28 15:40 test/
-rw-rw----  0 username groupname       0 Jul 28 15:40 test/a
Macbook> tar -xvf test.tar
x test/a
x test/b
x test/a
x test/
x test/a
Macbook> 

Também tentei alterar as permissões no teste / a para 000, anexando-o ao arquivo e, em seguida, acrescentando outro teste / a, mas esse também funcionou bem:

drwxrwx---  0 username groupname       0 Jul 28 15:40 test/
-rw-rw----  0 username groupname       0 Jul 28 15:40 test/a
-rw-rw----  0 username groupname       0 Jul 28 15:40 test/b
dr-xr-x---  0 username groupname       0 Jul 28 15:40 test/
----------  0 username groupname       0 Jul 28 15:40 test/a
-rw-rw----  0 username groupname       0 Jul 28 15:40 test/a

Então, eu realmente gostaria de ver o arquivo original que causou o problema e o que poderia estar naquele arquivo para causar esse problema.

Se um nome de arquivo e um diretório compartilham o mesmo nome, o tar tem um problema ao extrair, mas há uma mensagem de erro bastante clara:

Macbook> tar -xvf test.tar
x test/
x test/dir1/
x test/dir1/a
x test/
x test/dir1: Can't remove already-existing dir
tar: Error exit delayed from previous errors.

(se o conflito aconteceu ao contrário, ou seja, um arquivo veio primeiro, um diretório com o mesmo nome veio depois, o tar o remove e cria o diretório:

Macbook> tar -xvf test.tar
x test/
x test/dir1
x test/
x test/dir1/
x test/dir1/a
Johnny
fonte
1
Deixei um pouco mais claro que o comportamento em seu Gist (e em sua resposta automática) não parece ser a resposta completa porque duplicatas de arquivos são permitidas em um arquivo tar. Portanto, a resposta para "Não consigo descompactar um arquivo tar com um arquivo duplicado" não deve ser "Remover o arquivo duplicado", pois o tar deve ser capaz de lidar com esse caso.
Johnny
2
Este é realmente um comentário - ele não oferece uma solução, é apenas uma discussão sobre uma solução existente. Johnny, você pode mudar isso para um comentário? Voltarei e excluirei isso mais tarde, só queria lhe dar uma chance de movê-lo primeiro. Obrigado.
Ian C.
2
@ Johnny, esta informação tem informações super valiosas, mas não é uma resposta para a pergunta. É um comentário sobre outra resposta. Pense da seguinte maneira: se a resposta de Geoff fosse excluída, essa resposta seria útil? Não, não seria. Realmente, o conteúdo desta resposta é "que outra resposta de Geoff não parece correta". A pergunta original era "O que está causando esse erro?" O mais próximo que você conseguiu responder foi "Não sei o que está causando isso, mas não é um arquivo duplicado" - mas isso exigiria uma edição e ainda não responde à pergunta original.
DW
2
Eu prefiro que isso não seja excluído, pois a imagem maior é que este é um lugar para aprender, e os detalhes neste post são impressionantes da OMI. É necessário marcar com +1 e não é necessário excluir - acho que isso ajudará outras pessoas em uma situação semelhante a descobrir se não possuem o arquivo corrompido do OP ou se a interação com a corrupção é diferente, não é?
Bmike
2
@bmike e outros: adicionei uma resposta que deveria pelo menos explicar o que está acontecendo aqui, embora não necessariamente o porquê.
Adam Liter
6

Acontece que o utilitário tar do OS X foi o correto! Houve realmente um erro no arquivo. Esse segmento de email discute isso com mais detalhes, mas o problema é que há um arquivo duplicado no arquivo morto . O pessoal do SCIP está consertando o arquivo enquanto digito isso.

[edit]
O scip-3.2.0.tgz recém-atualizado agora está sendo extraído muito bem! O hash SHA-1 do novo tgz é 5b4e8283f4a5bf9e50f9a62d4320d6f5f50c8476.

[editar 2]
Não é que haja um erro no arquivo. Simplesmente bsdtar, que é fornecido com o OS X, lida com arquivos duplicados de maneira diferente gnutar, que é fornecido com o Linux. A resposta de @Adam Liter aqui fornece uma explicação completa do que está acontecendo.

Geoff
fonte
1
Interessante. Então, talvez os outros utilitários estivessem ignorando o erro de arquivo duplicado e seguindo em frente sem reclamar? De qualquer forma, feliz que você encontrou a causa e a resposta.
TryTryAgain
1
Sim, acho que é exatamente isso que os outros utilitários estão fazendo. Eu diria que o utilitário tar do OS X é o correto aqui. Um arquivo mal formado sempre deve gerar pelo menos um aviso para alertar o usuário de que algo está errado. Obrigado pela ajuda!
Geoff
Um arquivo duplicado em um arquivo tar não o torna um arquivo malformado, o formato tar permite especificamente dupes. Estou curioso para saber por que o seu mac tar se recusou a descompactar o arquivo, mesmo que você não especificou a -kopção, o que faria com que fosse avisado sobre arquivos preexistentes. Infelizmente, eles já atualizaram o scip-3.2.0.tgzarquivo para remover o dupe, então não posso testar esse arquivo.
Johnny
O tarextrato reage de maneira diferente ao tentar extrair scip-3.2.0/applications/Coloring/Makefileduas vezes, dependendo do seu umask. Se o primeiro criado não deixar um acesso de gravação, a segunda tentativa falhará.
dan
1
@ DW Adicionei uma resposta que explica por que isso não é uma contradição.
Adam Liter
1

Existe um software de arquivamento alternativo, gratuito e leve que eu uso no Mac OSX. Chama-se Keka e eu o uso para descompactar o 7zip mais especificamente. Além disso, ele pode descompactar outros tipos como .rar, .tar, .gz etc. Também funcionou para o arquivo tar específico do OP, mas tentei depois que o @Geoff mencionou que a equipe estava trabalhando na reparação do arquivo.

ThisClark
fonte