Sự khác biệt giữa dịch vụ xargs và thay thế lệnh?


14

Trong nhiều trường hợp tôi sử dụng thay thế lệnh thay vì xargs. Ví dụ rm $(ls)giống nhưls | xargs rm

Điều gì thực sự là sự khác biệt giữa chúng?

Tôi nghĩ một trong những khác biệt là sự thay thế lệnh chạy trong subshell trong khi xargschạy trong shell hiện tại nhưng tôi không chắc chắn.

Hãy liệt kê sự khác biệt.

Câu trả lời:


9

Một điểm khác biệt là khi sử dụng thay thế lệnh thay vì đường ống, kích thước của dữ liệu được truyền bị giới hạn bởi kích thước của bộ đệm lệnh, do đó, nó bị cắt ngắn trong một số trường hợp không có cảnh báo. Điều này cũng có nghĩa là toàn bộ đầu ra lệnh phải được tạo ra và được lưu trữ trong bộ nhớ, trước khi nó được chuyển sang lệnh tiếp theo, vì vậy đối với các đầu ra lớn, bạn có thể sử dụng nhiều bộ nhớ hơn mức cần thiết.

Một vấn đề khác với phương thức đầu tiên là đầu ra được phân chia trên khoảng trắng, vì vậy bạn không thể xử lý tên tệp có khoảng trắng trong chúng. xargscũng bị ảnh hưởng bởi vấn đề khoảng trắng, nhưng nó có thể được khắc phục bằng cách thay đổi dấu phân cách được sử dụng. Để xử lý đúng tên tệp bằng cách này, bạn sẽ cần sử dụng byte null làm dấu phân cách trong ví dụ thứ hai.

Một vấn đề thứ ba là các khối được mở rộng, vì vậy nếu một tệp có dấu hoa thị hoặc dấu hỏi trong tên của nó, sẽ có kết quả không mong muốn.

Bạn có thể tìm thấy một cuộc thảo luận thú vị về vấn đề này tại đây: http://mywiki.wooledge.org/ParsingLs

Cú pháp đúng sẽ là

echo rm *

hoặc nếu bạn phải sử dụng xargs,

find . -maxdepth 1 -print0 | xargs -0 echo rm

Loại bỏ echokhi đầu ra có vẻ đúng.


1
@Sinoosh: xargscũng chạy trong một lớp con do đường ống, trừ khi bạn kích hoạt shopt -s lastpipe, trong trường hợp đó, nó sẽ chạy trong trình bao hiện tại. Tôi không nghĩ rằng việc chạy trong một subshell là một vấn đề mặc dù trong trường hợp này, vì bạn không thay đổi bất kỳ biến nào.
user000001

1
@Sinoosh: Để truyền từng đối số một, bạn có thể sử dụng -lcờ, như thế nào find . -maxdepth 1 -print0 | xargs -0 -l rm. Đối với câu hỏi thứ hai, bạn không thể sử dụng lsvới xargs -0vì ls không chia sản lượng trên Bute null, nhưng với dòng mới (mà là hợp lệ trong tên tập tin BTW)
user000001

1
@Sinoosh: Không phải đoạn đầu tiên, mà là đoạn thứ hai: xargs mà không có -0tùy chọn bị vấn đề khoảng trắng.
user000001

1
Đọc man xargs, sử dụng echođể thử nghiệm, không rm. xargscho phép chúng tôi vượt quá giới hạn shell (một số bộ đệm được giới hạn ở 65K, danh sách tên tệp thì không).
ví von

1
@Sinoosh: Tôi không có tài liệu tham khảo tốt, nhưng bạn có thể nhập xargs --show-limitsvà bạn sẽ thấy giới hạn được đặt trên hệ thống của mình,
user000001
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.