これは、Johnnyのanswerで何が起きているのかを特定するのに役立ち、MacではなくLinuxでこれが機能する理由の質問に答える必要があります。
問題は、bsdtar
ほとんどのLinuxシステムが使用するのに対して、Mac OS Xが使用するという事実にありますgnutar
。
あなたは、インストールすることができますgnutar
使用して、自作してMac上でbrew install gnu-tar
シンボリックリンクであろう、gnutar
に/usr/local/bin
のようにgtar
。
をインストールするとgnutar
、ジョニーの答えの手順を使用して問題を再現できます。
$ 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
そのため、明らかに、重複を詰まらgnutar
せるような方法で物事を異なる方法でアーカイブしbsdtar
ます。のgtar -ztvf test.tar.gz
2番目のインスタンスがtest/a
aとしてアーカイブされることを示すという事実link to test/a
は関連しています。ジョニーがコメントで指摘しているようにgnutar
、実際のファイルではなく、ハードリンクとして重複を保存し--hard-dereference
ます。
つまり、次のことができます。
$ 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
ただし、この場合、明らかにtarballの作成を制御しないため--hard-dereference
、オプションはありません。幸いなことに、OPの回答に基づいて、この問題はアップストリームによって修正されたようです。
それでも、将来この問題が発生し、迅速な修正が必要な場合、またはアップストリームのメンテナーが応答しない場合は、回避策があります。
重複ファイルが何であるかを特定したら、次の--fast-read
オプションを使用できますbsdtar
(このオプションはの一部でありbsdtar
、ではなくの 一部であることに注意してください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.
したがって、ジョニーの答えのおもちゃの例に従って作成したおもちゃの例では、重複ファイルはtest/a
です。したがって、次の操作を行うことにより、この問題を回避できます。
# 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
さらに、gnutar
この--hard-dereference
オプションを使用しなかった場合でも、それ自体で作成された複製を含むアーカイブをアンパックして完全に満足できることに注意してください。
$ rm -r test
$ gtar -xvf test.tar.gz
test/
test/a
test/b
test/a
$ echo $?
0
$ ls test/
a b
したがって、これはMacではエラーがスローされ、Linuxではエラーがスローされない理由に関する質問に答えます。(ほとんど)Linuxディストリビューションにgnutar
はが同梱されておりgnutar
、tarballはおそらくパッケージ化されているので、解凍時にエラーは発生しませんが、解凍gnutar
時にエラーが発生しbsdtar
ます。
さらに読み、参照するために、bsdtarとGNU tarの違いは何ですか?Unix.SEで。