Mengapa mengekstrak tgz ini membuat kesalahan pada Mac saya tetapi tidak pada Linux?

27

Saya mengalami masalah yang agak aneh, dan saya tidak tahu apa yang terjadi. Saya memiliki file tgz, scip-3.2.0.tgz , yang melempar kesalahan ketika saya mencoba membongkar itu. Kesalahan hanya terjadi pada OS X (Saya di 10.10.4). Saya dapat mengekstrak file tanpa kesalahan pada kotak Linux yang menjalankan CentOS 6.6. Kesalahan terjadi ketika keduanya menggunakan perintah baris tarperintah dan saat menggunakan utilitas arsip. Saya mengirim email ke milis SCIP, dan saya memiliki hash SHA-1 yang sama dengan pengguna lain ( e085a4a3591eddf945dcb365d97d2512c267e374), jadi tidak ada kesalahan unduhan. Mereka tidak yakin apa yang sedang terjadi.

Inilah kesalahan yang saya dapatkan ketika saya mencoba membongkar menggunakan utilitas arsip:

kesalahan utilitas arsip

Jika gambar pernah rusak, teks dalam gambar mengatakan ini:

Tidak dapat memperluas "scip-3.2.0.tgz" ke "Desktop".
(Kesalahan 1 - Operasi tidak diizinkan.)

Dan ketika saya mencoba membongkar melalui baris perintah, ini adalah output yang saya dapatkan . Ini baris terakhir ( tar: Error exit delayed from previous errors.) yang menjadi perhatian saya. Saya tidak melihat apa yang menyebabkannya. Arsip tampaknya mengekstraksi tanpa masalah, tapi saya tidak percaya dengan kesalahan yang dilemparkan.

Adakah yang tahu apa yang menyebabkan ini?

[sunting]
Melihat sedikit lebih dekat pada output, baris 1108 berisi kesalahan:

x scip-3.2.0/applications/Coloring/Makefile: Can't create 'scip-3.2.0/applications/Coloring/Makefile'
Geoff
sumber
2
Apakah itu berfungsi dengan aplikasi lain seperti unarchiver? wakaba.c3.cx/s/apps/unarchiver.html
TryTryAgain
Ya, benar! Saya ingin tahu apa yang mereka lakukan secara berbeda. Sebagian masalahnya adalah bahwa saya memiliki skrip bash yang mengotomatiskan banyak hal, dan salah satu hal yang perlu dilakukan adalah mengekstrak tgz ini sehingga dapat membangun apa yang ada di dalamnya. Saya ingin tahu apakah ada bug dalam tarperintah yang datang dengan OS X.
Geoff
1
Sangat mungkin, ada bug. Saya menemukan utilitas arsip OS X bawaan cukup jelek. Apakah tidak ada cara Anda dapat kembali mengarsipkan file yang diperlukan menjadi zip atau sesuatu? Juga, jika Anda membuat skrip, apakah kesalahan juga terjadi ketika Anda gunzip -c scip-3.2.0.tgz | tar xopf -dari baris perintah, karena Anda akan menggunakannya untuk skrip Anda?
TryTryAgain
Ya, perintah itu melempar kesalahan yang sama. gunzipberfungsi dengan baik, tetapi ketika saya mencoba untuk mengekstrak tarball terkompresi, saat itulah kesalahan terlempar.
Geoff
Ah, ternyata memang ada kesalahan di tarball! Saya tidak gila. Saya akan menulis jawaban yang lebih rinci. Ternyata utilitas tar di OS X adalah yang benar di sini!
Geoff

Jawaban:

32

Ini akan membantu mengidentifikasi apa yang terjadi dalam jawaban Johnny , serta menjawab pertanyaan mengapa ini bekerja di Linux tetapi tidak untuk Mac.

Masalahnya terletak pada kenyataan bahwa Mac OS X menggunakan bsdtar, sedangkan sebagian besar sistem Linux menggunakan gnutar.

Anda dapat menginstal gnutarpada Mac dengan Homebrew, menggunakan brew install gnu-tar, yang akan symlink gnutarke /usr/local/binsebagai gtar.

Jika Anda menginstal gnutar, maka Anda dapat mereproduksi masalah menggunakan langkah-langkah dalam jawaban 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

Jadi jelas gnutarmengarsipkan berbagai hal dengan cara yang menyebabkan bsdtartersedak duplikat. Fakta yang gtar -ztvf test.tar.gzmenunjukkan bahwa instance kedua test/adiarsipkan sebagai link to test/arelevan. Seperti yang ditunjukkan Johnny dalam komentar, gnutarakan menyimpan duplikat sebagai tautan keras daripada file yang sebenarnya, yang dapat dinonaktifkan --hard-dereference.

Artinya, Anda bisa melakukan hal berikut:

$ 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

Namun, dalam hal ini, Anda jelas tidak mengontrol pembuatan tarball, jadi --hard-dereferencebukan pilihan. Untungnya, berdasarkan jawaban OP , tampaknya masalah ini telah diperbaiki oleh hulu.

Meskipun demikian, jika ada orang lain yang mengalami masalah ini di masa depan dan membutuhkan perbaikan cepat atau memiliki pengelola hulu yang tidak responsif, ada solusinya.

Setelah Anda mengidentifikasi apa file duplikat itu, Anda dapat menggunakan --fast-readopsi bsdtar(perhatikan bahwa opsi ini hanya bagian dari bsdtar, bukan 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.

Jadi, dalam contoh mainan yang saya buat mengikuti contoh mainan di jawaban Johnny , file duplikatnya test/a. Dengan demikian, Anda dapat menghindari masalah ini dengan melakukan hal berikut:

# 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

Catatan, apalagi, yang gnutarsangat senang membongkar arsip dengan duplikat yang dibuat dengan sendirinya, bahkan ketika --hard-dereferenceopsi tidak digunakan:

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

Jadi ini menjawab pertanyaan Anda mengapa ada kesalahan pada Mac tetapi tidak pada Linux. (Sebagian besar) distro Linux dikirim bersama gnutar, dan karena tarball mungkin dikemas dengan gnutar, tidak akan ada kesalahan saat membongkar gnutar, tetapi akan ada kesalahan saat membongkar bsdtar.


Untuk bacaan dan referensi lebih lanjut, orang mungkin ingin melihat Apa perbedaan antara tar bsdtar dan GNU? di Unix.SE.

Adam Liter
sumber
Wow, bagus sleuthing, saya tidak tahu bahwa ada perbedaan yang signifikan antara gnutar dan tar bsd. Berdasarkan pada Anda gtar -tcvf, gnutar cukup "pintar" untuk mengoptimalkan file salinan kedua sebagai tautan alih-alih menggandakannya dalam arsip.
Johnny
Setelah menjelajahi dokumen, sepertinya ini adalah efek samping dari penanganan hard link gtar. Tampaknya berpikir bahwa file duplikat sebenarnya adalah tautan keras ke file tersebut, sehingga menyimpannya sebagai tautan alih-alih file yang sebenarnya. Memberi gtar --hard-dereferenceopsi menonaktifkan perilaku ini.
Johnny
@ Johnny Benar-benar dua orang penjaga Homebrew yang menemukan ini (Misty De Meo dan Dominyk Tiller). Seorang pengelola beberapa perangkat lunak yang saya gunakan merilis versi baru dengan file duplikat di tarball, yang menyebabkan masalah ketika mencoba menginstal versi baru dengan Homebrew (jelas). Bagaimanapun, terima kasih telah memeriksa dokumen! Saya akan menambahkan itu ke jawabannya.
Adam Liter
Ini luar biasa. Saya menandai jawaban ini karena ini adalah penjelasan paling menyeluruh tentang apa yang terjadi. Terima kasih!
Geoff
7

Keberadaan file duplikat dalam arsip tidak boleh membuatnya tidak valid atau tidak dapat diekstraksi di OSX, karena secara default, tar menimpa duplikat.

Jadi, aku sedikit bingung dengan perilaku di Intisari Anda - OSX tar memungkinkan untuk file duplikat dalam arsip (sebuah kemunduran untuk tujuan aslinya sebagai t kera ar lokio utilitas, sehingga memungkinkan file yang akan ditambahkan ke akhir dari arsip kaset, dan ketika arsip dipulihkan, versi terbaru file akan menimpa versi yang lebih lama

Hanya ketika opsi "-k" muncul, tar harus memperingatkan tentang file yang sudah ada sebelumnya.

Di sini saya membuat arsip dengan file duplikat kemudian diekstraksi tanpa masalah. Tidak sampai saya menambahkan opsi -k yang memperingatkan saya tentang file duplikat:

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

Masalah umask yang sederhana tampaknya juga bukan penyebabnya, saya mencoba mengubah umask saya menjadi 0777 dan saya masih dapat mengekstrak arsip:

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

Saya pikir saya bisa menduplikasi masalah dengan sengaja menambahkan direktori yang tidak dapat ditulis ke arsip, tetapi itu tidak berhasil, tar tidak memperbarui izin pada direktori ketika mengekstrak arsip:

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> 

Saya juga mencoba mengubah izin pada tes / a ke 000, menambahkannya ke arsip, lalu menambahkan tes lain / a, tetapi yang bekerja dengan baik juga:

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

Jadi saya benar-benar ingin melihat arsip asli yang menyebabkan masalah dan melihat apa yang ada di arsip itu yang menyebabkan masalah ini.

Jika nama file dan direktori berbagi nama yang sama, tar memang memiliki masalah penggalian, tetapi memiliki pesan kesalahan yang cukup jelas:

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.

(jika konflik terjadi sebaliknya, yaitu file datang pertama, maka direktori dengan nama yang sama datang kemudian, tar hanya menghapusnya dan membuat direktori:

Macbook> tar -xvf test.tar
x test/
x test/dir1
x test/
x test/dir1/
x test/dir1/a
Johnny
sumber
1
Saya membuatnya sedikit lebih jelas bahwa perilaku dalam Gist-nya (dan jawabannya sendiri) tampaknya bukan jawaban penuh karena duplikat file diperbolehkan dalam arsip tar. Jadi jawaban untuk "Saya tidak bisa membongkar arsip tar dengan file duplikat" tidak boleh "Hapus file duplikat" karena tar seharusnya mampu menangani kasus itu.
Johnny
2
Ini benar-benar komentar - tidak menawarkan solusi, itu hanya diskusi tentang solusi yang ada. Johnny, bisa tolong pindahkan ini ke komentar? Saya akan kembali dan menghapusnya nanti, hanya ingin memberi Anda kesempatan untuk memindahkannya terlebih dahulu. Terima kasih.
Ian C.
2
@ Johnny, informasi ini memang memiliki informasi yang sangat berharga, tetapi itu bukan jawaban untuk pertanyaan itu. Ini komentar tentang jawaban lain. Pikirkan seperti ini: jika jawaban Geoff dihapus, apakah jawaban ini bermanfaat? Tidak, tidak akan. Sungguh, isi dari jawaban ini adalah "bahwa jawaban lain oleh Geoff tampaknya tidak benar". Pertanyaan aslinya adalah "Apa yang menyebabkan kesalahan ini?" Jawaban terdekat yang bisa Anda dapatkan adalah "Saya tidak tahu apa penyebabnya, tapi itu bukan file duplikat" - tetapi itu akan membutuhkan suntingan, dan masih belum benar-benar menjawab pertanyaan awal.
DW
2
Saya lebih suka ini tidak dihapus karena gambar yang lebih besar adalah ini adalah tempat untuk belajar, dan detail dalam posting ini luar biasa IMO. +1 dan tidak perlu menghapus - saya pikir ini akan membantu orang lain dalam situasi yang sama mencari tahu jika mereka tidak memiliki file korup OP atau interaksi korupsi berbeda, bukan?
bmike
2
@bmike dan lain-lain: Saya telah menambahkan jawaban yang setidaknya harus menjelaskan apa yang sedang terjadi di sini, meskipun tidak selalu mengapa.
Adam Liter
6

Ternyata utilitas tar OS X adalah yang benar! Memang ada kesalahan dalam arsip. Utas email ini membahasnya lebih detail, tetapi masalahnya adalah ada file duplikat di arsip . Orang-orang SCIP sedang memperbaiki arsip saat saya mengetik ini.

[sunting]
Scip-3.2.0.tgz yang baru diperbarui sekarang mengekstraksi dengan baik! Hash SHA-1 dari tgz baru adalah 5b4e8283f4a5bf9e50f9a62d4320d6f5f50c8476.

[sunting 2]
Bukannya ada kesalahan dalam arsip. Hanya itu bsdtar, yang dikirimkan dengan OS X, menangani file duplikat berbeda dari gnutar, yang dikirimkan dengan Linux. @Adam Liter jawaban di sini memberikan penjelasan menyeluruh tentang apa yang terjadi.

Geoff
sumber
1
Menarik. Jadi mungkin utilitas lain mengabaikan kesalahan file duplikat dan melanjutkan tanpa mengeluh? Bagaimanapun, senang Anda menemukan penyebab dan jawabannya.
TryTryAgain
1
Ya, saya pikir itulah tepatnya yang dilakukan utilitas lain. Saya berpendapat bahwa utilitas tar OS X adalah yang benar di sini. Arsip yang cacat harus selalu memunculkan setidaknya peringatan untuk memperingatkan pengguna bahwa ada sesuatu yang tidak aktif. Terima kasih atas bantuan Anda!
Geoff
File duplikat dalam arsip tar tidak menjadikannya arsip yang cacat, format tar khusus memungkinkan untuk dupes. Saya ingin tahu mengapa tar mac Anda menolak membongkar arsip meskipun Anda tidak menentukan -kopsi, yang akan membuatnya memperingatkan tentang file yang sudah ada sebelumnya. Sayangnya, mereka telah memperbarui scip-3.2.0.tgzfile untuk menghapus dupe, jadi saya tidak dapat menguji arsip itu.
Johnny
The tarekstrak bereaksi secara berbeda setelah mencoba untuk mengekstrak scip-3.2.0/applications/Coloring/Makefiledua kali tergantung pada Anda umask. Jika yang pertama dibuat tidak memberikan Anda akses tulis, upaya ke-2 gagal.
dan
1
@ WD Saya telah menambahkan jawaban yang menjelaskan mengapa ini bukan kontradiksi.
Adam Liter
1

Ada perangkat lunak arsip alternatif, gratis, ringan yang saya gunakan untuk Mac OSX. Ini disebut Keka dan saya menggunakannya untuk membongkar 7zip paling khusus. Selain itu, ia dapat membongkar jenis lain seperti .rar, .tar, .gz dll. Ini juga berfungsi untuk file tar khusus OP, tetapi saya mencobanya setelah @Geoff menyebutkan bahwa tim sedang memperbaiki file tersebut.

Klik ini
sumber