Tại sao trích xuất tgz này lại gây ra lỗi trên máy Mac của tôi mà không phải trên Linux?


27

Tôi đang gặp một vấn đề khá kỳ lạ và tôi không thể hiểu chuyện gì đang xảy ra. Tôi có một tệp tgz, scip-3.2.0.tgz , đó là một lỗi khi tôi cố gắng giải nén nó. Lỗi chỉ xảy ra trên OS X (Tôi là ngày 10.10.4). Tôi có thể giải nén tệp mà không gặp lỗi trên hộp Linux chạy CentOS 6.6. Lỗi xảy ra khi cả hai sử dụng lệnh dòng tarlệnh và khi sử dụng tiện ích lưu trữ. Tôi đã gửi email danh sách gửi thư SCIP và tôi có cùng hàm băm SHA-1 với người dùng khác ( e085a4a3591eddf945dcb365d97d2512c267e374), do đó không có lỗi tải xuống. Họ không chắc chắn những gì đang xảy ra.

Đây là lỗi tôi gặp phải khi cố gắng giải nén bằng tiện ích lưu trữ:

lỗi lưu trữ tiện ích

Trong trường hợp hình ảnh bị hỏng, văn bản trong hình ảnh cho biết điều này:

Không thể mở rộng "scip-3.2.0.tgz" thành "Máy tính để bàn".
(Lỗi 1 - Thao tác không được phép.)

Và khi tôi cố gắng giải nén thông qua dòng lệnh, đây là đầu ra tôi nhận được . Đó là dòng cuối cùng ( tar: Error exit delayed from previous errors.) liên quan đến tôi. Tôi không thấy những gì gây ra nó. Các kho lưu trữ dường như trích xuất mà không có vấn đề, nhưng tôi không tin nó với lỗi đó được ném.

Có ai biết những gì gây ra điều này?

[sửa]
Nhìn kỹ hơn một chút ở đầu ra, dòng 1108 có lỗi:

x scip-3.2.0/applications/Coloring/Makefile: Can't create 'scip-3.2.0/applications/Coloring/Makefile'

2
Nó có hoạt động với một ứng dụng khác như unarchiver không? wakaba.c3.cx/s/apps/unarchiver.html
TryTryAgain

Vâng, đúng vậy! Tôi tự hỏi những gì họ đang làm khác nhau. Một phần của vấn đề là tôi có một tập lệnh bash tự động hóa một loạt các thứ, và một trong những điều nó cần làm là trích xuất tgz này để nó có thể xây dựng những gì bên trong nó. Tôi tự hỏi nếu có lỗi trong tarlệnh đi kèm với OS X.
Geoff

1
Rất có thể, có một lỗi. Tôi đã tìm thấy tiện ích lưu trữ được xây dựng trong OS X khá tệ. Không có cách nào bạn có thể lưu trữ lại các tập tin cần thiết vào một zip hoặc một cái gì đó? Ngoài ra, nếu bạn đang viết kịch bản, có phải lỗi cũng xảy ra khi bạn gunzip -c scip-3.2.0.tgz | tar xopf -từ dòng lệnh, như bạn sẽ sử dụng nó cho tập lệnh của mình không?
TryTryAgain

Vâng, lệnh đó ném lỗi tương tự. gunzipchỉ hoạt động tốt, nhưng khi tôi cố gắng giải nén tarball không nén, đó là khi lỗi bị ném.
Geoff

Ah, hóa ra có một lỗi trong tarball! Tôi không bị điên. Tôi sẽ viết lên một câu trả lời chi tiết hơn. Rõ ràng tiện ích tar trong OS X là chính xác ở đây!
Geoff

Câu trả lời:


32

Điều này sẽ giúp xác định những gì đang diễn ra trong câu trả lời của Johnny , cũng như trả lời câu hỏi tại sao điều này hoạt động trên Linux mà không phải là Mac.

Vấn đề nằm ở chỗ Mac OS X sử dụng bsdtar, trong khi hầu hết các hệ thống Linux đều sử dụng gnutar.

Bạn có thể cài đặt gnutartrên máy Mac với Homebrew, bằng cách sử dụng brew install gnu-tar, sẽ liên kết gnutarvới nhau /usr/local/bindưới dạng gtar.

Nếu bạn cài đặt gnutar, thì bạn có thể tái tạo vấn đề bằng các bước trong câu trả lời của 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

Vì vậy, rõ ràng gnutarlưu trữ những thứ khác nhau theo cách gây ra bsdtarnghẹt thở trên các bản sao. Thực tế cho thấy gtar -ztvf test.tar.gzrằng phiên bản thứ hai test/ađược lưu trữ dưới dạng link to test/acó liên quan. Như Johnny chỉ ra trong các bình luận, gnutarsẽ lưu trữ các bản sao dưới dạng liên kết cứng thay vì tệp thực tế, có thể bị vô hiệu hóa --hard-dereference.

Đó là, bạn có thể làm như sau:

$ 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

Tuy nhiên, trong trường hợp này, rõ ràng bạn không kiểm soát việc tạo tarball, vì vậy --hard-dereferencekhông phải là một lựa chọn. May mắn thay, dựa trên câu trả lời của OP , có vẻ như vấn đề này đã được khắc phục bằng cách ngược dòng.

Tuy nhiên, nếu bất kỳ ai khác gặp phải vấn đề này trong tương lai và cần khắc phục nhanh hoặc có một người bảo trì ngược dòng không phản hồi, có một cách giải quyết.

Khi bạn xác định tệp trùng lặp là gì, bạn có thể sử dụng --fast-readtùy chọn bsdtar(lưu ý rằng tùy chọn này chỉ là một phần của bsdtar, không phải 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.

Vì vậy, trong ví dụ về đồ chơi mà tôi đã tạo theo ví dụ về đồ chơi trong câu trả lời của Johnny , tệp trùng lặp là test/a. Vì vậy, bạn có thể tránh vấn đề này bằng cách làm như sau:

# 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

Lưu ý, hơn nữa, điều đó gnutarhoàn toàn vui khi giải nén một kho lưu trữ với các bản sao được tạo bởi chính nó, ngay cả khi --hard-dereferencetùy chọn không được sử dụng:

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

Vì vậy, điều này trả lời câu hỏi của bạn về lý do tại sao một lỗi được ném trên Mac mà không phải là Linux. (Hầu hết) Linux phân phối cùng với gnutar, và vì tarball có lẽ được đóng gói cùng gnutar, nên sẽ không có lỗi khi giải nén gnutar, nhưng sẽ có lỗi khi giải nén bsdtar.


Để đọc thêm và tham khảo, người ta có thể muốn xem Sự khác biệt giữa bsdtar và GNU tar là gì? trên Unix.SE.


Wow, điều tra tốt đẹp, tôi không biết rằng có bất kỳ sự khác biệt đáng kể nào giữa gnutar và bsd tar. Dựa trên của bạn gtar -tcvf, gnutar đủ "thông minh" để tối ưu hóa tập tin sao chép thứ hai dưới dạng liên kết thay vì sao chép nó trong kho lưu trữ.
Johnny

Sau khi quét các tài liệu, có vẻ như đây là tác dụng phụ của việc xử lý liên kết cứng của gtar. Dường như nghĩ rằng tệp trùng lặp thực sự là một liên kết cứng đến tệp, vì vậy nó lưu trữ dưới dạng liên kết thay vì tệp thực tế. Cho gtar --hard-dereferencetùy chọn vô hiệu hóa hành vi này.
Johnny

@ John John Đó thực sự là hai trong số những người duy trì Homebrew đã tìm ra điều này (Misty De Meo và Dominyk Tiller). Một người duy trì một số phần mềm mà tôi sử dụng đã phát hành một phiên bản mới với một tệp trùng lặp trong tarball, điều này gây ra sự cố khi cố gắng cài đặt phiên bản mới với Homebrew (rõ ràng). Dù sao, cảm ơn bạn đã kiểm tra các tài liệu! Tôi sẽ thêm nó vào câu trả lời.
Adam Văn

Thật tuyệt vời. Tôi đánh dấu đây là câu trả lời vì đây là lời giải thích kỹ lưỡng nhất về những gì đang diễn ra. Cảm ơn!
Geoff

7

Sự tồn tại của một tệp trùng lặp trong kho lưu trữ sẽ không làm cho nó không hợp lệ hoặc không thể trích xuất được trên OSX, vì theo mặc định, tar ghi đè lên các bản sao.

Vì vậy, tôi hơi bối rối bởi hành vi trong Gist - OSX tar của bạn cho phép các tệp trùng lặp trong kho lưu trữ (trở lại mục đích ban đầu của nó là tiện ích t ape ar chive , vì vậy nó cho phép các tệp được thêm vào cuối kho lưu trữ băng và khi kho lưu trữ được khôi phục, phiên bản mới nhất của tệp sẽ ghi đè lên (các) phiên bản cũ hơn)

Chỉ khi tùy chọn "-k" xuất hiện, tar sẽ cảnh báo về các tệp có sẵn.

Ở đây tôi đã tạo một kho lưu trữ với một tệp trùng lặp sau đó giải nén nó mà không gặp vấn đề gì. Mãi đến khi tôi thêm tùy chọn -k, nó mới cảnh báo tôi về tệp trùng lặp:

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

Một vấn đề đơn giản về ô dù dường như cũng không phải là thủ phạm, tôi đã thử thay đổi ô của mình thành 0777 và tôi vẫn có thể trích xuất kho lưu trữ:

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

Tôi nghĩ rằng tôi có thể nhân đôi vấn đề bằng cách cố tình thêm một thư mục không thể ghi vào kho lưu trữ, nhưng điều đó không hiệu quả, tar đã không cập nhật các quyền trên thư mục khi trích xuất kho lưu trữ:

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> 

Tôi cũng đã thử thay đổi các quyền trong bài kiểm tra / a thành 000, nối nó vào kho lưu trữ, sau đó nối thêm một bài kiểm tra khác / a, nhưng điều đó cũng hoạt động tốt:

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

Vì vậy, tôi thực sự muốn xem kho lưu trữ ban đầu gây ra sự cố và xem những gì có thể có trong kho lưu trữ đó để gây ra sự cố này.

Nếu một tên tệp và thư mục chia sẻ cùng tên, tar có vấn đề giải nén, nhưng nó có một thông báo lỗi khá rõ ràng:

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.

(nếu xung đột xảy ra theo cách khác, tức là một tệp đến trước, sau đó một thư mục có cùng tên đến sau, tar chỉ xóa nó và tạo thư mục:

Macbook> tar -xvf test.tar
x test/
x test/dir1
x test/
x test/dir1/
x test/dir1/a

1
Tôi đã nói rõ hơn một chút rằng hành vi trong Gist của anh ấy (và tự trả lời của anh ấy) dường như không phải là câu trả lời đầy đủ vì các bản sao tệp được cho phép trong kho lưu trữ tar. Vì vậy, câu trả lời cho "Tôi không thể giải nén tệp lưu trữ tar với tệp trùng lặp" không nên là "Xóa tệp trùng lặp" vì tar được cho là có thể xử lý trường hợp đó.
Johnny

2
Đây thực sự là một nhận xét - nó không cung cấp giải pháp, nó chỉ thảo luận về một giải pháp hiện có. Johnny, bạn có thể vui lòng chuyển nó đến một bình luận? Tôi sẽ quay lại và xóa cái này sau, chỉ muốn cho bạn cơ hội để di chuyển nó trước. Cảm ơn.
Ian C.

2
@Johnny, thông tin này không có thông tin siêu giá trị, nhưng nó không phải là một câu trả lời cho câu hỏi này. Đó là một nhận xét về một câu trả lời khác. Hãy nghĩ về nó theo cách này: nếu câu trả lời của Geoff bị xóa, câu trả lời này có hữu ích không? Không, nó sẽ không. Thực sự, nội dung của câu trả lời này là "câu trả lời khác của Geoff có vẻ không đúng". Câu hỏi ban đầu là "Điều gì gây ra lỗi này?" Cách gần nhất mà bạn có thể trả lời đó là "Tôi không biết điều gì gây ra nó, nhưng đó không phải là một tệp trùng lặp" - nhưng điều đó sẽ yêu cầu chỉnh sửa và vẫn không thực sự trả lời câu hỏi ban đầu.
DW

2
Tôi muốn thay vì điều này không bị xóa vì bức tranh lớn hơn là đây là một nơi để tìm hiểu và các chi tiết trong bài viết này là IMO tuyệt vời. +1 và không cần xóa - Tôi nghĩ rằng nó sẽ giúp những người khác trong tình huống tương tự tìm ra nếu họ không có tệp bị hỏng của OP hoặc tương tác tham nhũng là khác nhau, phải không?
bmike

2
@bmike và những người khác: Tôi đã thêm một câu trả lời ít nhất nên giải thích những gì đang diễn ra ở đây, mặc dù không nhất thiết là tại sao.
Adam Văn

6

Hóa ra tiện ích tar của OS X là chính xác! Thực sự có một lỗi trong kho lưu trữ. Chủ đề email này thảo luận chi tiết hơn, nhưng vấn đề là có một tệp trùng lặp trong kho lưu trữ . Các anh chàng SCIP đang sửa chữa kho lưu trữ khi tôi gõ cái này.

[sửa]
Scip-3.2.0.tgz mới được cập nhật hiện đang giải nén tốt! Hàm băm SHA-1 của tgz mới là 5b4e8283f4a5bf9e50f9a62d4320d6f5f50c8476.

[sửa 2]
Không phải là có lỗi trong kho lưu trữ. Đơn giản là bsdtar, nó đi kèm với OS X, xử lý các tệp trùng lặp khác với gnutar, đi cùng với Linux. Câu trả lời của @Adam Liter ở đây cung cấp một lời giải thích kỹ lưỡng về những gì đang xảy ra.


1
Hấp dẫn. Vì vậy, có thể các tiện ích khác đã bỏ qua lỗi tập tin trùng lặp và tiếp tục mà không phàn nàn? Dù sao, vui mừng bạn tìm thấy nguyên nhân và câu trả lời.
TryTryAgain

1
Vâng, tôi nghĩ đó chính xác là những gì các tiện ích khác đang làm. Tôi sẽ tranh luận rằng tiện ích tar của OS X là đúng ở đây. Một kho lưu trữ không đúng định dạng phải luôn đưa ra ít nhất một cảnh báo để cảnh báo người dùng rằng có gì đó bị tắt. Cảm ơn bạn đã giúp đỡ!
Geoff

Một tệp trùng lặp trong kho lưu trữ tar không làm cho nó trở thành một kho lưu trữ không đúng định dạng, định dạng tar đặc biệt cho phép sao chép. Tôi tò mò tại sao mac tar của bạn từ chối giải nén tệp lưu trữ mặc dù bạn không chỉ định -ktùy chọn cụ thể , điều này sẽ khiến nó cảnh báo về các tệp có sẵn. Thật không may, họ đã cập nhật scip-3.2.0.tgztệp để xóa bản sao, vì vậy tôi không thể kiểm tra kho lưu trữ đó.
Johnny

Các tartrích xuất phản ứng khác nhau khi cố gắng giải nén scip-3.2.0/applications/Coloring/Makefilehai lần tùy thuộc vào của bạn umask. Nếu lần đầu tiên được tạo không để lại cho bạn quyền truy cập ghi, lần thử thứ 2 không thành công.
dan

1
@DW Tôi đã thêm một câu trả lời giải thích tại sao đây không phải là mâu thuẫn.
Adam Văn

1

Có một phần mềm lưu trữ nhẹ, miễn phí, thay thế mà tôi sử dụng cho Mac OSX. Nó được gọi là Keka và tôi sử dụng nó để giải nén 7zip cụ thể nhất. Hơn nữa, nó có thể giải nén các loại khác như .rar, .tar, .gz, v.v. Nó cũng hoạt động cho tệp tar cụ thể của OP, nhưng tôi đã thử sau khi @Geoff đề cập đến nhóm đang sửa chữa tệp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.