2009-03-25 27 views
6

Có thể ai đó vui lòng cho tôi ví dụ về việc sử dụng xargs trong hoạt động dưới đây không?Cách sử dụng "xargs" đúng cách khi danh sách đối số quá dài

tar c $dir/temp/*.parse\ 
    | lzma -9 > $dir/backup/$(date '+%Y-%m-%d')-archive.tar.lzma 

tôi nhận được lỗi từ bash "/bin/tar: Đối số danh sách quá dài"

Particularily Tôi cố gắng để làm nén LZMA vào khoảng 4.500 hồ sơ; vì vậy điều này không đáng ngạc nhiên. Tôi chỉ không biết làm thế nào để sửa đổi ở trên để sử dụng xargs và thoát khỏi lỗi! Cảm ơn.

Trả lời

10

Mở rộng trên CristopheDs trả lời và giả sử bạn đang sử dụng bash:

tar c --files-from <(find $dir/temp -maxdepth 1 -name "*.parse") | lzma -9 > $dir/backup/$(date '+%Y-%m-%d')-archive.tar.lzma 

Lý do xargs không giúp bạn ở đây là nó sẽ làm nhiều lời gọi đến khi tất cả đối số đã được sử dụng. Điều này sẽ không giúp bạn ở đây vì điều đó sẽ tạo ra một số lưu trữ tar mà bạn không muốn.

+0

tôi đã làm sai với việc tìm kiếm nhiều lần xâm nhập tar trước đây, suy nghĩ khi đưa chúng vào {...} | lzma ... nó hoạt động. nhưng sau đó nó sẽ in lại tiêu đề tar mỗi lần: p –

+0

Tuyệt vời, đây là một giải pháp hoàn hảo; cảm ơn! – jparanich

+1

Trong trường hợp bất cứ ai tìm thấy điều này và không rõ ràng * cách nó hoạt động, '<(command)' trong bash tạo ra một "tên mô tả tập tin" gắn liền với đầu ra của 'lệnh'. Vì vậy, trong trường hợp này, 'tar' thấy một đối số như' --files-from/dev/fd123', nhưng đọc từ "tệp" '/ dev/fd123' chỉ cung cấp cho nó đầu ra của' find', mà không cần cho một tệp tạm thời thực sự. – IMSoP

4

Sử dụng tìm cách đặt tên tệp 'muốn' thành tệp tạm thời, và sau đó sử dụng tar với tùy chọn dòng lệnh '-–files-from'.

Edit:

hoặc ống chúng trực tiếp vào nhau để tránh các tập tin tạm thời.

Vì vậy: hãy sử dụng tìm danh sách các tên tệp mong muốn | tar ... --files-từ

4

Có lẽ bạn muốn một cái gì đó như thế này?

find $dir/temp/ -name '*.parse' -print0 | tar --null -T - -c | lzma -9 > $dir/backup/$(date '+%Y-%m-%d')-archive.tar.lzma 
+1

+1, đây là những gì tôi sắp viết. – ashawley

0

Kể từ khi bạn đang ở trên Linux, bạn có GNU tar, và bạn có thể sử dụng '-F -' hoặc '--files-from' tùy chọn để đọc các tên tập tin.

Tuy nhiên, bạn cũng có thể sử dụng:

--Sử dụng-nén-program = "LZMA -9"

để xác định chương trình nén để sử dụng, và chỉ đơn giản là cung cấp cho các gạc nộp tên như mục tiêu tập tin cho lệnh 'tar'.

Điều này là cần thiết để nén 'bzip2' trước khi tùy chọn '-j' được thêm vào.

11

Lưu ý phụ:

Luôn luôn, luôn tránh xargs (1). Đó là một công cụ bị hỏng và chỉ hữu ích từ xa nếu bạn sử dụng nó với tùy chọn -0. Thậm chí sau đó, nó hầu như luôn luôn tốt hơn để sử dụng tùy chọn -exec tìm (1), hoặc một vòng lặp đơn giản cho hoặc trong khi.

Tại sao xargs quá tệ? Thứ nhất, nó chia tách đầu vào trên khoảng trắng, có nghĩa là tất cả các tên tệp của bạn mà chứa khoảng trắng sẽ gây ra sự cố. Thứ hai, số cố gắng làm smartass và báo giá phân tích cú pháp cho bạn. Điều này chỉ khiến bạn đau đầu hơn khi bạn sử dụng tên tệp trên chứa trích dẫn như một phần của tên tệp, chẳng hạn như bài hát: "Tôi không muốn bỏ lỡ một điều.mp3".Điều này sẽ chỉ làm xargs nôn và nguyền rủa với bạn rằng bạn trích dẫn đầu vào của nó xấu. Không, bạn đã không: chỉ nên biết rằng các báo giá không thuộc về dữ liệu đầu vào, chúng thuộc về các tập lệnh shell và xargs không có doanh nghiệp nào cố gắng phân tích chúng.

Hãy nhớ bạn, xargs (1) không thực hiện phân tách khoảng trắng hoặc phân tích cú pháp trích dẫn khi bạn chuyển -0 cho nó. Nó thực hiện quyền , sử dụng byte NULL để phân định tên tệp. Nhưng điều đó có nghĩa là bạn cần cung cấp cho nó đầu vào sử dụng các tên tệp được phân cách bằng byte NULL (chẳng hạn như "find -foo -print0"). Điều này đưa chúng ta trở lại: tốt hơn là chỉ cần sử dụng find -exec: "find -foo -exec bar {} +".

+0

đẹp, ít lịch sử/giải thích tuyệt vời - được đánh giá cao! – jparanich

+1

Đây là lý do tại sao GNU Parallel được thực hiện: http://www.gnu.org/software/parallel/history.html –

Các vấn đề liên quan