Lệnh xargs: cách dùng, tùy chọn -n và -I, kết hợp với find
Lệnh xargs là công cụ Linux biến các dòng và từ nhận từ đầu vào chuẩn thành đối số của một lệnh khác rồi chạy lệnh đó. Khi chuyển ba tệp nhật ký do find tìm thấy cho wc qua xargs trong thư mục làm việc trên máy chủ AlmaLinux 9, một tệp có dấu cách trong tên bị tách làm hai và gây lỗi, còn khi thêm -print0 và -0 thì số dòng của cả ba tệp đều hiện ra.
Đầu ra bên dưới được chạy trong thư mục làm việc bằng tài khoản root trên máy chủ AlmaLinux 9.8. Danh sách tên, nhật ký và tệp tạm là các tệp mẫu tạo để thử nghiệm, và địa chỉ IP cùng đường dẫn thư mục trong đó cũng là giá trị ví dụ.
1️⃣ Cách dùng cơ bản của lệnh xargs
xargs chia đầu vào chuẩn do lệnh trước chuyển đến theo khoảng trắng và xuống dòng, rồi chạy lệnh viết phía sau với các phần đó làm đối số. Chúng tôi kiểm tra bằng names.txt có mỗi dòng một tên.
cat names.txtalice
bob
carol
dave
erinKhi chuyển đầu ra của cat cho xargs echo, năm dòng trở thành đối số của một lần echo và hiện trên một dòng.
cat names.txt | xargs echoalice bob carol dave erinNếu không viết lệnh phía sau, xargs chạy echo, nên kết quả như nhau.
cat names.txt | xargsalice bob carol dave erinĐường ống nối đầu ra của lệnh trước với đầu vào chuẩn của lệnh sau, nên không có gì đi vào đối số của lệnh sau. Nếu chỉ chuyển list.txt chứa ba tên tệp qua đường ống cho wc -l, wc đếm 3 dòng của chính danh sách.
cat list.txtlogs/access.log
logs/error.log
tmp/keep.txtcat list.txt | wc -l3Đặt xargs ở giữa thì ba tên trong danh sách trở thành đối số của wc và số dòng hiện theo từng tệp.
cat list.txt | xargs wc -l 3 logs/access.log
2 logs/error.log
1 tmp/keep.txt
6 total2️⃣ Tùy chọn -n và -I của xargs
Không có tùy chọn, toàn bộ đầu vào đi vào một lần chạy lệnh, nên để lặp lại lệnh, hãy dùng -n đặt số đối số chuyển mỗi lần. Hình bên dưới cho thấy cùng năm tên được gộp thế nào theo từng tùy chọn.
-n 1 chạy echo cho từng tên nên hiện năm dòng.
cat names.txt | xargs -n 1 echoalice
bob
carol
dave
erin-n 2 gộp từng hai tên và chuyển riêng tên còn lại.
cat names.txt | xargs -n 2 echoalice bob
carol dave
erinĐể xem các lệnh được chạy, hãy thêm -t. Dòng lệnh hiện trước, đầu ra theo sau bên dưới.
cat names.txt | xargs -t -n 2 echoecho alice bob
alice bob
echo carol dave
carol dave
echo erin
erinNếu đối số phải nằm ở chỗ khác ngoài cuối lệnh, hãy đặt ký tự giữ chỗ bằng -I. Từng dòng đi vào vị trí {}, và nếu cùng chữ xuất hiện nhiều lần thì tất cả đều được thay.
cat names.txt | xargs -I {} echo 'user: {}'user: alice
user: bob
user: carol
user: dave
user: erincat names.txt | xargs -I {} echo '{} -> home/{}'alice -> home/alice
bob -> home/bob
carol -> home/carol
dave -> home/dave
erin -> home/erinTheo cách tương tự, bạn có thể tạo thư mục theo từng tên. Tạo thư mục home trước rồi dùng -I {} tạo thư mục theo tên bên dưới, sẽ có năm thư mục.
mkdir homecat names.txt | xargs -I {} mkdir home/{}ls homealice bob carol dave erin-I coi một dòng là một đối số nên không dùng cùng -n được. Khi viết cả hai, -I bị bỏ qua kèm cảnh báo và {} được in nguyên chữ.
cat names.txt | xargs -I {} -n 2 echo {}xargs: warning: options --replace and --max-args/-n are mutually exclusive, ignoring previous --replace value
{} alice bob
{} carol dave
{} erin-L gộp theo số dòng. Nếu một dòng có nhiều từ, các từ đó được chuyển cùng nhau, và với names.txt mỗi dòng một tên, -L 2 cho kết quả giống -n 2.
cat names.txt | xargs -L 2 echoalice bob
carol dave
erin3️⃣ Kết hợp find và xargs
Không cần tự tạo danh sách tên, bạn có thể chuyển thẳng các tệp find tìm thấy cho xargs. Tìm tệp kết thúc bằng .log trong thư mục nhật ký sẽ thấy ba tệp, trong đó một tệp có dấu cách trong tên.
find /root/work/logs -name '*.log'/root/work/logs/access.log
/root/work/logs/error.log
/root/work/logs/old access.logKhi chuyển nguyên danh sách này cho xargs wc -l, tên có dấu cách bị tách thành old và access.log, hiện hai dòng lỗi và tổng chỉ là 5 dòng của hai tệp.
find /root/work/logs -name '*.log' | xargs wc -l 3 /root/work/logs/access.log
2 /root/work/logs/error.log
wc: /root/work/logs/old: No such file or directory
wc: access.log: No such file or directory
5 total-print0 của find ngăn cách tên bằng ký tự null thay vì xuống dòng, còn -0 của xargs chỉ chia đối số theo ký tự null đó. Dùng cả hai thì hiện số dòng của cả ba tệp, kể cả tệp có dấu cách.
find /root/work/logs -name '*.log' -print0 | xargs -0 wc -l 3 /root/work/logs/access.log
2 /root/work/logs/error.log
1 /root/work/logs/old access.log
6 totalTùy chọn -exec của find cũng làm được việc này. Thêm + sau {} thì các tệp tìm thấy được chuyển một lần nên kết quả như nhau, và find giữ nguyên dấu cách trong tên tệp. xargs còn nhận đầu ra của các lệnh khác, nên hãy dùng khi đầu vào không chỉ đến từ find, hoặc khi cần đặt số lượng mỗi lần (-n) hay số lần chạy đồng thời (-P).
find /root/work/logs -name '*.log' -exec wc -l {} + 3 /root/work/logs/access.log
2 /root/work/logs/error.log
1 /root/work/logs/old access.log
6 totalĐể chỉ chọn các tệp tìm thấy có chứa một chuỗi, hãy thêm grep -l sau xargs. Tệp chứa wp-login có hai: nhật ký truy cập và nhật ký lỗi.
find /root/work/logs -name '*.log' -print0 | xargs -0 grep -l wp-login/root/work/logs/access.log
/root/work/logs/error.log4️⃣ Xóa tệp bằng lệnh xargs
Thêm rm sau xargs thì các tệp tìm thấy bị xóa một lần, nên hãy kiểm tra trước tệp nào sẽ được chuyển. Đặt echo trước rm thì chỉ hiện dòng lệnh sẽ chạy và tệp vẫn còn nguyên.
find /root/work/tmp -name '*.tmp' -print0 | xargs -0 echo rmrm /root/work/tmp/cache-a.tmp /root/work/tmp/cache-b.tmp /root/work/tmp/cache-c.tmpls tmpcache-a.tmp cache-b.tmp cache-c.tmp keep.txtVới -p, xargs hỏi từng lệnh có chạy không. Nhập n thì không xóa gì và ba tệp tạm vẫn còn.
find /root/work/tmp -name '*.tmp' -print0 | xargs -0 -p rmrm /root/work/tmp/cache-a.tmp /root/work/tmp/cache-b.tmp /root/work/tmp/cache-c.tmp?...nls tmpcache-a.tmp cache-b.tmp cache-c.tmp keep.txtNhập y thì ba tệp bị xóa, chỉ còn keep.txt.
find /root/work/tmp -name '*.tmp' -print0 | xargs -0 -p rmrm /root/work/tmp/cache-a.tmp /root/work/tmp/cache-b.tmp /root/work/tmp/cache-c.tmp?...yls tmpkeep.txtNếu đầu vào trống, xargs chạy lệnh một lần không có đối số. Chuyển tệp trống thì rm chạy không có đối số và báo lỗi [rm: missing operand]; thêm -r thì lệnh không chạy.
cat empty.txt | xargs rmrm: missing operand
Try 'rm --help' for more information.cat empty.txt | xargs -r rm5️⃣ Chạy song song, dấu phân cách và tùy chọn của xargs
🔲 Chạy song song và dấu phân cách
Khi lệnh chạy lần lượt từng cái, thời gian tăng theo số mục tiêu. -P đặt số lệnh chạy đồng thời. Bốn lệnh sleep chờ 1, 2, 3 và 4 giây mất 10 giây khi chạy lần lượt, và xong trong 4 giây, thời gian dài nhất, khi chạy đồng thời với -P 4.
time seq 1 4 | xargs -n 1 sleep
real 0m10.007s
user 0m0.004s
sys 0m0.003stime seq 1 4 | xargs -n 1 -P 4 sleep
real 0m4.005s
user 0m0.001s
sys 0m0.006sNếu đầu vào được chia bằng ký hiệu khác xuống dòng hay khoảng trắng, hãy đặt dấu phân cách bằng -d. Chia ba tên nối bằng dấu phẩy với -d , sẽ hiện mỗi tên một dòng.
printf 'alice,bob,carol' | xargs -d , -n 1 echoalice
bob
carolĐể đọc từ tệp thay vì đầu vào chuẩn, hãy ghi tên tệp ở -a. Năm tên trong names.txt được chuyển cho echo mà không cần đường ống.
xargs -a names.txt echoalice bob carol dave erin🔲 Tùy chọn của lệnh xargs
📌 Tùy chọn chính: kết quả chạy trong bài này
| Tùy chọn | Chức năng | Kết quả trong bài này | |
|---|---|---|---|
| -n | Đặt số đối số chuyển cho một lần chạy lệnh | Năm tên được gộp theo cặp bằng -n 2 và echo chạy ba lần | |
| -I | Đặt từng dòng vào ký tự giữ chỗ và chạy theo dòng | Tên đi vào vị trí {}; viết cùng -n thì -I bị bỏ qua kèm cảnh báo | |
| -L | Đặt số dòng chuyển cho một lần chạy lệnh | Với tệp mỗi dòng một tên, kết quả giống -n 2 | |
| -t | In dòng lệnh sẽ chạy trước | Dòng lệnh hiện trước đầu ra | |
| -0 | Chỉ chia đầu vào theo ký tự null (dùng cùng find -print0) | Không có thì tên có dấu cách bị tách và có hai dòng lỗi; có thì cả ba tệp đều 6 dòng | |
| -p | Hỏi từng lệnh có chạy không | n thì còn nguyên, y thì xóa ba tệp | |
| -r | Không chạy lệnh nếu đầu vào trống | Không có thì [rm: missing operand], có thì không chạy | |
| -P | Đặt số lệnh chạy đồng thời | Bốn lệnh sleep: lần lượt 10 giây, với -P 4 là 4 giây | |
| -d | Đặt dấu phân cách để chia đầu vào | -d , cho mỗi tên một dòng | |
| -a | Đọc đầu vào từ tệp thay vì đầu vào chuẩn | Năm tên trong names.txt đi vào một lần echo |
📎 Tùy chọn khác: theo tài liệu hướng dẫn chính thức
| Tùy chọn | Chức năng | |
|---|---|---|
| -s | Đặt số ký tự tối đa của một dòng lệnh | |
| -x | Vượt kích thước -s thì kết thúc mà không chạy | |
| -E | Ngừng đọc đầu vào khi gặp dòng chỉ có chữ này | |
| -o | Mở lại terminal làm đầu vào chuẩn của lệnh (cho chương trình tương tác) | |
| --process-slot-var | Đặt số khác nhau vào biến môi trường cho mỗi lệnh chạy đồng thời |
🔲 Trình mô phỏng lệnh xargs
Trong trình mô phỏng bên dưới, bạn có thể tự nhập lệnh xargs và find trên cùng các tệp thử nghiệm.
🔢 FAQ & nội dung đề xuất
Tìm chuỗi
Lệnh grep trên Linux
Lệnh grep tìm các dòng trong tệp khớp với chuỗi và biểu thức chính quy. Dùng để tìm cùng lúc trong nhiều tệp chuyển qua xargs.
Xóa tệp
Lệnh rm của Linux
Bài viết về lệnh rm xóa tệp và thư mục, cùng mối nguy của tùy chọn -rf. Hãy kiểm tra tùy chọn trước khi đặt rm sau xargs.
Kết thúc tiến trình
Lệnh kill của Linux
Lệnh kill gửi tín hiệu đến số tiến trình để kết thúc nó. Dùng tiếp khi chuyển danh sách số tiến trình qua xargs để kết thúc.
ℹ️ Thông báo tiếp thị liên kết
Nội dung trên trang này có chứa liên kết affiliate (tiếp thị liên kết). Khi khách truy cập mua sản phẩm hoặc dịch vụ qua các liên kết này, trang sẽ nhận hoa hồng từ bên bán. Trong quá trình đó, số tiền người mua phải trả (sẽ giảm khi có chương trình khuyến mãi ↓) không hề tăng lên. Giá, khuyến mãi và tình trạng hàng được đăng theo thời điểm viết bài và có thể khác với thực tế, vì vậy hãy kiểm tra lại lần cuối với bên bán trước khi mua. Việc chọn và đánh giá sản phẩm dựa trên tiêu chí riêng của trang; việc có nhận hoa hồng hay không không ảnh hưởng đến thứ tự giới thiệu hay nội dung đánh giá.