Đổi tên thư mục bên trong một kho lưu trữ tar


14

Có thể đổi tên một thư mục bên trong một kho lưu trữ tar? Trường hợp sử dụng của tôi là tôi có một tệp spec RPM được cung cấp bên ngoài giả định tarball có cấu trúc thư mục nhất định và tôi có một tarball được cung cấp bên ngoài có tên thư mục cấp cao nhất không khớp với những gì tệp spec mong đợi. Tôi không kiểm soát tập lệnh tạo tarball hoặc tệp thông số RPM, vì vậy tôi không thể thay đổi tập lệnh để khớp với tập lệnh khác.

Những gì tôi đã làm là giải mã, thay đổi tên thư mục và sau đó tạo một tarball mới, nhưng tôi đã tự hỏi liệu có cách nào khác để làm điều đó không.


3
Thật không may, tôi nghi ngờ điều đó, nhưng tôi muốn biết liệu có ai khác có cách nào không. Tôi nghĩ rằng đặt cược tốt nhất của bạn là viết một kịch bản để gỡ rối, đổi tên và tái lập.
Kevin

Câu trả lời:


8

Không nên quá khó, ít nhất là đối với các tài liệu lưu trữ tương thích với định dạng kiểu cũ, nơi tên tệp được lưu trữ trong trường có kích thước cố định (100 byte), nhưng tôi không biết bất kỳ công cụ nào có thể đổi tên tập tin tại chỗ trong một kho lưu trữ tar. Ngoài ra, với kho lưu trữ nén, bạn vẫn cần tạo một tệp mới.

Nó thậm chí còn dễ dàng hơn, nhưng tôi không biết bất kỳ công cụ hiện có nào có thể lọc một kho lưu trữ, đổi tên các tệp khi nó đi. Bạn có thể xây dựng một trên đầu các thư viện tar trong các ngôn ngữ kịch bản; ví dụ: đây là tập lệnh Proof-of-Concept để đổi tên một thư mục trong kho lưu trữ tar bằng Perl vớiArchive::Tar . Các kho lưu trữ được tải hoàn toàn vào bộ nhớ; đây là một hạn chế nội tại của Archive::Tar.

#!/usr/bin/env perl
## Usage: tar-rename OLDPREFIX NEWPREFIX
use strict;
use warnings;
use Archive::Tar;
my ($from, $to) = @ARGV;
my $tar = Archive::Tar->new(\*STDIN);
foreach my $file ($tar->get_files()) {
    my $name = $file->name;
    $name =~ s~\A\Q$from\E($|/)~$to$1~;
    $file->rename($name) unless $name eq $file->name;
}
$tar->write(\*STDOUT);

GNU tar không có khả năng đổi tên thành viên một cách nhanh chóng, nhưng pax(thay thế cho POSIX cho cpiotar) thì có. Tuy nhiên, bạn không thể thực hiện paxcả đọc và viết từ kho lưu trữ. Những gì bạn có thể làm là hiển thị kho lưu trữ dưới dạng cây thông thường thông qua AVFS và tạo một kho lưu trữ mới với pax. Điều này giữ lại tên tệp (trừ khi được chuyển đổi), nội dung, thời gian và chế độ nhưng đặt lại quyền sở hữu tệp cho bạn (trừ khi được thực hiện dưới quyền root).

mountavfs
cd "~/.avfs$PWD/old.tgz#"
pax -w -s '!bar!baz!' -s '!bar/!baz/' . | gzip >new.tgz

GNU Tar đã có --transformít nhất là năm 2010 cho phép đổi tên các tệp một cách nhanh chóng. Ví dụ: xem: scriptsandoneliners.blogspot.com/2019/11/iêu
A.Danischewski

@ A.Danischewski --transformcho phép bạn đổi tên các tệp khi bạn xây dựng hoặc trích xuất một kho lưu trữ. Nhưng làm thế nào để bạn đổi tên các tập tin trong một kho lưu trữ mà không giải nén nó? (Trích xuất không phải là một giải pháp tốt: bạn có thể không có đủ dung lượng đĩa; bạn có thể không có quyền để lưu giữ thông tin quyền sở hữu; bạn có thể không có khả năng lưu giữ dấu thời gian chính xác ...)
Gilles 'SO- ngừng trở nên xấu xa'

Được rồi, tôi vừa thấy bài đăng của bạn nói rằng "GNU tar không có khả năng đổi tên thành viên một cách nhanh chóng" - nó thực hiện nhưng chỉ trên đường vào / ra. Nếu bạn muốn thay đổi tên trong kho lưu trữ hiện có, bạn có thể sử dụng lưu trữ để gắn kết nó vào một thư mục, thay đổi bất kỳ tên nào bạn muốn và ngắt kết nối nó.
A.Danischewski

3

Cả câu trả lời của sr_'s hack và Gilles đều rất tốt, nhưng nếu vấn đề của bạn chỉ là tên thư mục gốc của tarball mục tiêu, trong khi chạy rpmbuild, một giải pháp khác có thể là xác định lại %setupmacro để thực hiện đổi tên thư mục cần thiết.

Một cái gì đó tương tự (bạn sẽ phải điều chỉnh và tinh chỉnh này để cấu hình thực tế của bạn, đặc biệt là thay thế old-dirdesired-dirvà sử dụng các công cụ giải nén bên phải) này trong thư mục ~/.rpmmacros:

%setup cd ../BUILD \
rm -rf cd-player \
bunzip2 -dc ../SOURCES/%{name}-%{version}.tar.bz2 | tar -xvvf - \
if [ $? -ne 0 ]; then \
  exit $? \
fi \
mv <old-dir> <desired-dir> \
cd <desired-dir> \
cd ../BUILD/cd-player \
chmod -R a+rX,g-w,o-w .

Tôi sẽ không thành thật làm điều đó nếu không phải trong tình huống kỳ lạ nhất, nhưng bạn có thể là trường hợp :)



1

Hack xấu xí, nhưng có lẽ điều này giúp bạn, đánh lừa tarcác liên kết tượng trưng:

$ mkdir a b
$ date >> b/foo
$ tar zcvf b-foo.tgz b/foo
$ rm -rf b
$ ln -s a b

$ tar zxvf b-foo.tgz                                                              
x b/foo: Cannot extract through symlink b
tar: Error exit delayed from previous errors.
$ tar zxvPf b-foo.tgz                                                             
x b/foo
$ ls a
foo

Nghĩ về nó, có lẽ là không, vì rpmsẽ không cho phép bạn gây rối với các cuộc tranh cãi tar, phải không? (Chỉnh sửa: có thể một số tartập lệnh bao bọc phức tạp trong $PATHcó thể giúp bạn giải quyết vấn đề này.)

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.