Câu 1Đâu là mô tả đúng về việc xargs làm?
xargs — Xây dựng lệnh từ đầu vào chuẩn
Trải đầu vào chuẩn thành tham số với echo a b | xargs echo, chạy từng từ một với -n1, chèn giá trị vào {} bằng -I{}, và xử lý hàng loạt find . -name '*.log' | xargs — kèm sơ đồ và terminal trực tiếp.
Biến đầu vào chuẩn thành tham số — xargs và -n1
Pipe truyền đầu ra của lệnh trước thành đầu vào chuẩn của lệnh sau. Nhưng rm và echo không đọc đầu vào chuẩn — chúng chỉ xử lý các giá trị được viết làm tham số. xargs là lệnh nhận những gì có trên đầu vào chuẩn và sắp xếp lại thành tham số cho lệnh bạn viết phía sau nó, nên với echo a b | xargs echo, a và b trở thành tham số của echo ở cuối.
Mặc định, xargs truyền các từ nhận được tới một lần chạy duy nhất, gom lại càng nhiều càng tốt. Thêm -n1 thì nó tách chúng ra, chạy lệnh một lần cho mỗi từ.
| Cú pháp | Tác dụng |
|---|---|
| xargs | Trải đầu vào thành tham số và chạy lệnh |
xargs -n1 | Chạy lệnh một lần cho mỗi tham số |
xargs -I{} | Thay {} bằng đầu vào và chèn vào bất kỳ đâu |
find ... | xargs | Chạy một lần xử lý gom chung cho những gì tìm thấy |
| xargs echo rm | In ra lệnh sẽ chạy để kiểm tra trước |
echo được đưa qua pipe tới xargs làm đầu vào chuẩn và sắp xếp lại thành tham số. Một lần chạy gom chung, hay ba lần chạy từng từ một — đó là khác biệt mà -n1 tạo ra.printf 'one two three\n' | xargs echo got: # got: one two three (gom, 1 lần chạy)
printf 'one\ntwo\nthree\n' | xargs -n1 echo item: # item: one / item: two / item: three
Chuỗi thay thế và tích hợp find — -I{}
xargs -I{} xây dựng lệnh bằng cách chèn mỗi dòng đầu vào vào vị trí của `{}`. Vì {} có thể đặt ở bất kỳ đâu bạn muốn, kể cả giữa lệnh, bạn có thể chạy dạng như echo file_{}.txt — với văn bản cố định quanh giá trị — từng dòng một.
Khi bạn muốn chạy thứ gì đó trên các tệp mà find tìm ra, dạng find ... | xargs là chuẩn mực. xargs trải các đường dẫn mà find in ra thành tham số và chạy một lần xử lý gom chung trên kết quả tìm kiếm. Kết hợp với -I{} thì bạn có thể xử lý từng đường dẫn tìm thấy bằng cách chèn chúng từng cái một vào `{}`.
find in ra được truyền cho xargs theo 1 dòng = 1 mục, và -I{} chèn mỗi cái vào `{}` rồi chạy từng cái một.printf 'alpha\nbeta\n' | xargs -I{} echo 'name = {}' # name = alpha / name = beta
mkdir -p logs # tạo thư mục nguồn
touch logs/a.log logs/b.log # tạo 2 tệp
find logs -name '*.log' | xargs -I{} echo 'found {}' # found logs/a.log / found logs/b.log
Xử lý từng cái một — Chọn giữa -n1 và -I{}
Cả -n1 lẫn -I{} đều chạy lệnh từng mục một, nhưng chúng khác nhau ở vị trí giá trị đi vào và cách đầu vào được tách. -n1 truyền các từ (các đoạn cách nhau bởi dấu cách hoặc dòng mới) từng cái một làm tham số ở cuối lệnh. -I{} lấy các dòng từng cái một và chèn chúng vào vị trí bạn viết `{}`.
Dùng `-n1` khi bạn chỉ cần giá trị ở cuối, và `-I{}` khi bạn muốn văn bản cố định quanh giá trị, như {}.bak.
| Khía cạnh | `-n1` | `-I{}` |
|---|---|---|
| Vị trí giá trị đi vào | Xếp ở cuối lệnh | Vào nơi bạn viết {} |
| Đơn vị tách | Từ (tách theo dấu cách/dòng mới) | Dòng (1 dòng = 1 mục) |
| Phù hợp cho | Chỉ truyền tham số lần lượt | Tạo dạng có văn bản cố định quanh giá trị |
printf 'a\nb\n' | xargs -n1 echo prefix # prefix a / prefix b (ở cuối)
printf 'a\nb\n' | xargs -I{} echo {}_done # a_done / b_done (chèn giữa lệnh)
Xử lý hàng loạt trong thực tế — Kiểm tra trước khi chạy
Trong công việc thực tế, bạn dùng xargs để sao chép hàng loạt và xóa hàng loạt trên các đối tượng mà find thu thập. Vì -I{} có thể chèn cùng một giá trị vào hai vị trí trở lên, nó hoạt động với các lệnh nhận hai tham số như cp nguồn đích, cho phép bạn tạo bản sao lưu "tên gốc + .bak" cùng một lúc.
Đừng chạy ngay các thao tác không thể hoàn tác như rm. Nếu bạn chạy xargs echo rm trước xargs rm, lệnh sẽ chạy chỉ được in ra và không có gì bị xóa. Hãy kiểm tra các đối tượng được liệt kê, rồi bỏ echo và chạy thật — cách hai bước kiểm-tra-rồi-chạy này là cách an toàn.
echo trước rm để kiểm tra đối tượng bằng cách in ra trước, rồi chạy.mkdir -p cache
touch cache/a.tmp cache/b.tmp
find cache -name '*.tmp' | xargs echo rm # chỉ in ra rm cache/a.tmp cache/b.tmp
find cache -name '*.tmp' | xargs rm # chạy thật khi đã chắc
Kiểm tra kiến thức
Hãy trả lời từng câu hỏi một.
Câu 2printf 'a\nb\nc\n' | xargs -n1 echo hoạt động thế nào?
Câu 3{} đại diện cho gì trong xargs -I{}?