Tar một thư mục, nhưng không lưu trữ đường dẫn tuyệt đối đầy đủ trong kho lưu trữ


277

Tôi có lệnh sau trong phần kịch bản lệnh shell dự phòng:

tar -cjf site1.bz2 /var/www/site1/

Khi tôi liệt kê nội dung của kho lưu trữ, tôi nhận được:

tar -tf site1.bz2
var/www/site1/style.css
var/www/site1/index.html
var/www/site1/page2.html
var/www/site1/page3.html
var/www/site1/images/img1.png
var/www/site1/images/img2.png
var/www/site1/subdir/index.html

Nhưng tôi muốn xóa phần này /var/www/site1khỏi tên thư mục và tệp trong kho lưu trữ, để đơn giản hóa việc trích xuất và tránh cấu trúc thư mục không đổi vô dụng. Không bao giờ biết, trong trường hợp tôi sẽ trích xuất các trang web được sao lưu ở nơi lưu trữ dữ liệu web /var/www.

Đối với ví dụ trên, tôi muốn có:

tar -tf site1.bz2
style.css
index.html
page2.html
page3.html
images/img1.png
images/img2.png
subdir/index.html

Vì vậy, khi tôi giải nén, các tệp được trích xuất trong thư mục hiện tại và tôi không cần phải di chuyển các tệp được trích xuất sau đó, và để các cấu trúc thư mục con được giữ nguyên.

Đã có nhiều câu hỏi về tar và sao lưu trong stackoverflowvà ở những nơi khác trên web, nhưng hầu hết trong số họ yêu cầu bỏ toàn bộ cấu trúc thư mục con (làm phẳng), hoặc chỉ thêm hoặc xóa tên ban đầu / trong tên (tôi không ' t biết những gì nó thay đổi chính xác khi giải nén), nhưng không còn nữa.

Sau khi đọc một số giải pháp được tìm thấy ở đây và ở đó cũng như hướng dẫn, tôi đã thử:

tar -cjf site1.bz2 -C . /var/www/site1/
tar -cjf site1.bz2 -C / /var/www/site1/
tar -cjf site1.bz2 -C /var/www/site1/ /var/www/site1/
tar -cjf site1.bz2 --strip-components=3 /var/www/site1/

Nhưng không ai trong số họ làm việc theo cách tôi muốn. Một số không làm gì cả, một số khác không lưu trữ các thư mục con nữa.

Nó nằm trong tập lệnh shell dự phòng được khởi chạy bởi Cron, vì vậy tôi không biết rõ, người dùng nào chạy nó, đường dẫn và thư mục hiện tại là gì, vì vậy luôn luôn viết đường dẫn tuyệt đối cho mọi thứ và không muốn thay đổi thư mục hiện tại để tránh phá vỡ thứ gì đó hơn nữa trong tập lệnh (vì nó không chỉ sao lưu các trang web, mà còn cả cơ sở dữ liệu, sau đó gửi tất cả những thứ đó đến FTP, v.v.)

Làm thế nào để đạt được điều này?

Có phải tôi đã hiểu sai về cách thức hoạt động của tùy chọn -C?



Chà, -Cchỉ có nghĩa là "thay đổi thư mục", trong khi thay thế một đường dẫn (hoặc tiền tố) chỉ có thể được thực hiện bởi --transform. súng trường. superuser.com/questions/595510/prepend-prefix-in-tar/595512 bạn có thể đơn giản -C (thay đổi thư mục) và --transform nó: `` `tar cjf site1.bz2 --transform" s / ^ \. \ // $ targetbase / "-C / var / www / site1. `` `
Daniele Cruciani

Đây là một câu hỏi rất hay và đáng buồn là không có câu trả lời nào cho đến ngày nay là thỏa đáng. Chúng tôi vẫn chưa được nghe từ một người khôn ngoan nào đó về cách chúng tôi có thể trích xuất chỉ một tệp style.css (ví dụ ở trên) vào thư mục hiện tại mà không có bất kỳ tham chiếu nào đến vị trí ban đầu hoặc cây thư mục? Tôi không muốn làm lộn xộn thư mục hiện tại của mình với cấu trúc cây mới không mong muốn. Âm thanh như một thiếu sót nghiêm trọng của tarball đã bị bỏ qua trong nhiều năm.
elmclose

Câu trả lời:


382
tar -cjf site1.tar.bz2 -C /var/www/site1 .

Trong ví dụ trên, tar sẽ thay đổi thành thư mục /var/www/site1trước khi thực hiện công việc của nó vì tùy chọn -C /var/www/site1đã được đưa ra.

Từ man tar:

OTHER OPTIONS

  -C, --directory DIR
       change to directory DIR

152
Đừng bỏ lỡ dấu chấm ở cuối, điều đó rất quan trọng ;-)
Freedom_Ben

9
Nếu bạn cũng muốn chọn các tệp để sao lưu dựa trên ký tự đại diện thì sao? -C / var / www / site1 * .dat không hoạt động :(
Andy Lorenz

16
Dấu chấm nói tarđể lưu trữ mọi thứ trong thư mục hiện tại. Và -Cthiết lập thư mục hiện tại.
Lars Brinkhoff

21
Điều này làm việc tuyệt vời. Tôi thấy hữu ích để giữ tên thư mục (không phải là đường dẫn đầy đủ), vì vậy tôi đã làm như sau: tar -czvf site1.tar.gz -C /var/www/ site1(Lưu ý khoảng trắng, tôi vẫn đang sử dụng -C, để cd vào thư mục mẹ và chỉ định thư mục vào tar thay vì dấu chấm)
jorfus 9/12/2015

9
Tôi nhận được một dấu chấm hàng đầu trong đường dẫn của tar, ví dụ như ./folderslàm thế nào để loại bỏ nó?
Mika571

39

Các tùy chọn -Choạt động; chỉ để làm rõ tôi sẽ đăng 2 ví dụ:

  1. tạo ra một tarball không có đường dẫn đầy đủ: đường dẫn đầy đủ /home/testuser/workspace/project/application.warvà những gì chúng ta muốn chỉ là project/application.warnhư vậy:

    tar -cvf output_filename.tar  -C /home/testuser/workspace project

    Lưu ý: có một khoảng cách giữa workspaceproject; tar sẽ thay thế đường dẫn đầy đủ với chỉ project.

  2. trích xuất tarball với thay đổi đường dẫn đích (mặc định .là thư mục hiện tại)

    tar -xvf output_filename.tar -C /home/deploy/

    tarsẽ trích xuất tarball dựa trên đường dẫn đã cho và bảo toàn đường dẫn tạo; trong ví dụ của chúng tôi, tập tin application.warsẽ được trích xuất /home/deploy/project/application.war.

    /home/deploy: đưa ra trên trích xuất
    project: đưa ra khi tạo tarball

Lưu ý: nếu bạn muốn đặt tarball đã tạo trong thư mục đích, bạn chỉ cần thêm đường dẫn đích trước tên tarball. ví dụ:

tar -cvf /path/to/place/output_filename.tar  -C /home/testuser/workspace project

1
Làm thế nào để thêm ký tự đại diện để chọn tệp trong ví dụ cuối?
Siva

Vấn đề với các ký tự đại diện là phần vỏ mở rộng chúng thành tên tệp phù hợp và tar không mở rộng chúng nếu chúng được trích dẫn ...
Gert van den Berg

Tôi đã thử điều này trên Ubuntu 18.04 và không gặp may. Tôi không chắc chắn những gì tôi đang thiếu. Thiết bị xuất chuẩn của tôi hiển thị chính xác khi tôi đóng gói, nhưng khi tôi gỡ bỏ nó, nó vẫn có đường dẫn đầy đủ
sdc

14

Có vẻ -Ctùy chọn tối đa tar v2.8.3 không hoạt động nhất quán trên tất cả các nền tảng (HĐH). -Ctùy chọn được cho là thêm thư mục vào kho lưu trữ nhưng trên Mac và Ubuntu, nó thêm tiền tố đường dẫn tuyệt đối bên trong tệp tar.gz được tạo.

tar target_path/file.tar.gz -C source_path/source_dir

Do đó, giải pháp nhất quán và mạnh mẽ là cdvào nguồn_path (thư mục mẹ của source_dir) và chạy

tar target_path/file.tar.gz source_dir

hoặc là

tar -cf target_path/file.tar.gz source_dir

trong kịch bản của bạn. Điều này sẽ loại bỏ tiền tố đường dẫn tuyệt đối trong cấu trúc thư mục tệp tar.gz được tạo của bạn.


1
Sử dụng tùy chọn -C DID loại bỏ tiền tố đường dẫn tuyệt đối bên trong tệp tar.gz được tạo trên fedora 29. Câu trả lời của bạn có cụ thể đối với một số hệ thống không?
EL_DON

@EL_DON: Tôi đã không kiểm tra tùy chọn -C trên Fedora, nhưng phần mềm ứng dụng tar lý tưởng nên hoạt động ổn định trên mọi nền tảng trừ khi đó là lỗi trong ứng dụng tar. Tùy chọn -C, tôi đã thử nghiệm trên Mac 10.8 và Mac 10.13 và Ubuntu (phiên bản tôi không thể nhớ). Nhưng kể từ tar v2.8.3, lệnh đã được thay đổi thành tar -cf target_path / file.tar.gz source_dir và nếu bạn thêm tùy chọn -C, nó sẽ không xóa tiền tố đường dẫn tuyệt đối trong tệp tar.gz được tạo.
Chinthaka Senanayaka

Tôi đã thử nghiệm lại trên một hệ thống centOS. Sau khi tạo tất cả các đường dẫn trong ví dụ và chạy lệnh (có -cvfthêm sau tar), tôi thấy tệp tar.gz kết quả không có đường dẫn tuyệt đối bên trong nó, phù hợp với một số câu trả lời khác. Nếu bạn nghĩ tar bị hỏng hoặc lỗi thời trên cả hai hệ thống tôi đã sử dụng để thử nghiệm, vui lòng liên kết với một số tài liệu hỗ trợ câu trả lời của bạn. Tôi nghĩ rằng -Ctùy chọn thay đổi thư mục trước khi thực hiện (như trong các câu trả lời khác). Khi tôi bỏ qua nó, tar cố gắng thêm rác từ ./, bao gồm cả các đường dẫn từ bắt đầu ./.
EL_DON

Tôi đã sử dụng tài liệu này: linux.die.net/man/1/tar Có, tài liệu nói -C sẽ thực hiện thay đổi đường dẫn, nhưng trên Mac 10.13 của tôi thì nó không hoạt động. đây có thể là một hành vi không nhất quán của ứng dụng tar. Điều đó có nghĩa đây là một lỗi. Nếu bạn đang viết một tập lệnh shell để chạy trên tất cả các nền tảng unix thì tốt hơn nên an toàn với mã chạy sẽ hoạt động trên tất cả các hệ điều hành.
Chinthaka Senanayaka

Câu trả lời của bạn không nói rằng có thể có lỗi và giải pháp mạnh mẽ hơn cho khả năng tương thích đa nền tảng là cdtrước tiên. Câu trả lời của bạn nói rằng công cụ này hoạt động theo cách ngược lại với cách các tài liệu nói rằng nó hoạt động và cách nó hoạt động trên hệ thống của tôi, vì vậy đó là một câu trả lời sai. Bạn có thể dễ dàng sửa nó.
EL_DON

7

Lệnh sau sẽ tạo thư mục gốc "." và đặt tất cả các tệp từ thư mục được chỉ định vào nó.

tar -cjf site1.tar.bz2 -C /var/www/site1 .

Nếu bạn muốn đặt tất cả các tệp trong thư mục gốc của tệp tar, @chinthaka là đúng. Chỉ cần cd vào thư mục và làm:

tar -cjf target_path/file.tar.gz *

Điều này sẽ đặt tất cả các tệp trong cwd vào tệp tar dưới dạng tệp gốc.


1
Sử dụng * không lưu bất kỳ .files hoặc. Folders "ẩn" nào. (fyi, sử dụng -C cùng với * không thành công, trình bao mở rộng thư mục hiện tại, không phải là thư mục -C)
Xen2050

1

Sử dụng "điểm" dẫn đến việc tạo thư mục có tên "điểm" (trên Ubuntu 16).

tar -tf site1.bz2 -C /var/www/site1/ .

Tôi đã giải quyết vấn đề này chi tiết hơn và chuẩn bị một ví dụ. Ghi âm nhiều dòng, cộng với một ngoại lệ.

tar -tf site1.bz2\
    -C /var/www/site1/ style.css\
    -C /var/www/site1/ index.html\
    -C /var/www/site1/ page2.html\
    -C /var/www/site1/ page3.html\
    --exclude=images/*.zip\
    -C /var/www/site1/ images/
    -C /var/www/site1/ subdir/
/

Tại sao bạn gọi nó là "điểm"? Chỉ là ., đó là thư mục hiện tại. Trong bối cảnh tar.gzcấu trúc của, đó chỉ là mức cơ sở / gốc / cấp cao nhất, phải không?
EL_DON

Xem ảnh chụp để biết chi tiết hình ảnh . Cách của tôi là chính xác hơn để sử dụng, đó là ý kiến ​​của tôi.
Serge Asachev

0

Nếu bạn muốn lưu trữ một thư mục con và cắt đường dẫn thư mục con, lệnh này sẽ hữu ích:

tar -cjf site1.bz2 -C /var/www/ site1
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.