Lệnh xargs: cách dùng, tùy chọn -n và -I, kết hợp với find

Môi trường thử nghiệmHọ RHELAlmaLinux 9.8Tài khoản rootKiểm tra ngày 2026-10-29

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

  • ↪️ Đầu vào chuẩn thành đối số của lệnh

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.txt
alice
bob
carol
dave
erin

Khi 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 echo
alice bob carol dave erin

Nếu không viết lệnh phía sau, xargs chạy echo, nên kết quả như nhau.

cat names.txt | xargs
alice 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.txt
logs/access.log
logs/error.log
tmp/keep.txt
cat list.txt | wc -l
3

Đặ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 total

2️⃣ Tùy chọn -n và -I của xargs

  • ↪️ Kích thước nhóm, vị trí đối số và kiểm tra bằng -t

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.

🧩 Cách xargs gộp đầu vào chuẩn thành đối số của lệnh
Sơ đồ giải thích
⚙️ Tùy chọn
$ cat names.txt | xargs echo
$ cat names.txt | xargs -n 2 echo
$ cat names.txt | xargs -I {} echo 'user: {}'
① Đầu vào chuẩn (names.txt)alicebobcaroldaveerinMỗi dòng một tên, năm dòng.
② Gộp thành đối sốalicebobcaroldaveerinKhông có tùy chọn, năm tên thành một nhóm.alicebobcaroldaveerin-n 2 gộp từng hai tên, tên còn lại thành nhóm riêng.alicebobcaroldaveerin-I {} coi một dòng là một nhóm và đặt vào vị trí {}.
③ Lệnh được chạy và đầu raecho alice bob carol dave erinalice bob carol dave erinecho chạy một lần.echo alice bobecho carol daveecho erinecho chạy ba lần, mỗi nhóm một dòng.echo 'user: alice' echo 'user: bob' … năm lần cùng dạng đến erinuser: aliceuser: bobuser: caroluser: daveuser: erinecho chạy năm lần, tên được đặt vào vị trí {}.
Không có tùy chọn, xargs gắn mọi từ đọc từ đầu vào làm đối số của một lần chạy. Năm tên đi vào một lần echo và hiện trên một dòng.
Với -n 2, từ được gộp theo cặp và lệnh được lặp lại. Năm tên thành ba nhóm, nên echo chạy ba lần.
Với -I {}, một dòng được tính là một đơn vị, dòng đó được đặt vào vị trí {} trong lệnh và lệnh chạy theo từng dòng. Dùng khi đối số phải nằm ở chỗ khác ngoài cuối cùng.

-n 1 chạy echo cho từng tên nên hiện năm dòng.

cat names.txt | xargs -n 1 echo
alice
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 echo
alice 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 echo
echo alice bob
alice bob
echo carol dave
carol dave
echo erin
erin

Nế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: erin
cat names.txt | xargs -I {} echo '{} -> home/{}'
alice -> home/alice
bob -> home/bob
carol -> home/carol
dave -> home/dave
erin -> home/erin

Theo 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 home
cat names.txt | xargs -I {} mkdir home/{}
ls home
alice  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 echo
alice bob
carol dave
erin

3️⃣ Kết hợp find và xargs

  • ↪️ Chuyển tên tệp có dấu cách bằng -print0 và -0

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.log

Khi 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 total

Tù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.log

4️⃣ Xóa tệp bằng lệnh xargs

  • ↪️ Xem trước bằng echo và xác nhận bằng -p

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 rm
rm /root/work/tmp/cache-a.tmp /root/work/tmp/cache-b.tmp /root/work/tmp/cache-c.tmp
ls tmp
cache-a.tmp  cache-b.tmp  cache-c.tmp  keep.txt

Vớ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 rm
rm /root/work/tmp/cache-a.tmp /root/work/tmp/cache-b.tmp /root/work/tmp/cache-c.tmp?...n
ls tmp
cache-a.tmp  cache-b.tmp  cache-c.tmp  keep.txt

Nhập y thì ba tệp bị xóa, chỉ còn keep.txt.

find /root/work/tmp -name '*.tmp' -print0 | xargs -0 -p rm
rm /root/work/tmp/cache-a.tmp /root/work/tmp/cache-b.tmp /root/work/tmp/cache-c.tmp?...y
ls tmp
keep.txt

Nế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 rm
rm: missing operand
Try 'rm --help' for more information.
cat empty.txt | xargs -r rm

5️⃣ Chạy song song, dấu phân cách và tùy chọn của xargs

  • ↪️ Tùy chọn -P, -d, -a

🔲 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.003s
time seq 1 4 | xargs -n 1 -P 4 sleep

real	0m4.005s
user	0m0.001s
sys	0m0.006s

Nế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 echo
alice
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 echo
alice 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ọnChức năngKết quả trong bài này
-nĐặt số đối số chuyển cho một lần chạy lệnhNă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òngTê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ệnhVới tệp mỗi dòng một tên, kết quả giống -n 2
-tIn dòng lệnh sẽ chạy trướcDòng lệnh hiện trước đầu ra
-0Chỉ 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
-pHỏi từng lệnh có chạy khôngn thì còn nguyên, y thì xóa ba tệp
-rKhông chạy lệnh nếu đầu vào trốngKhông có thì [rm: missing operand], có thì không chạy
-PĐặt số lệnh chạy đồng thờiBố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ẩnNă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ọnChức năng
-sĐặt số ký tự tối đa của một dòng lệnh
-xVượt kích thước -s thì kết thúc mà không chạy
-ENgừng đọc đầu vào khi gặp dòng chỉ có chữ này
-oMở 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.

Trình mô phỏng lệnh xargsGNU findutils 4.8
[root@server work]#
Dùng phím ↑↓ trên bàn phím để gọi lại các lệnh đã gõ trước đó.

🔢 FAQ & nội dung đề xuất

Nếu chuyển số tiến trình, kill gửi tín hiệu đến số đó. Khi lấy số tiến trình của sleep 600 chạy nền bằng biến shell $! rồi chuyển cho xargs kill, [Terminated sleep 600] còn lại trong danh sách tác vụ và tác vụ biến mất ở lần jobs tiếp theo. Khi gom danh sách số bằng lệnh khác, hãy in trước xem gồm những tiến trình nào rồi mới chuyển.

Tùy chọn --show-limits in các giới hạn. Trên máy chủ thử nghiệm, giới hạn POSIX của độ dài dòng lệnh là 2,093,890 byte, và bộ đệm lệnh xargs thực sự dùng là 131,072 byte. Theo tài liệu, nếu đầu vào dài hơn bộ đệm này, xargs chia lệnh thành nhiều lần chạy.

Chỉ cần một lệnh do xargs chạy thất bại với mã từ 1 đến 125, mã thoát của xargs là 123. Cả lần chạy wc có tên tệp bị tách và lần chạy rm với đầu vào trống đều là 123, còn trường hợp không tìm thấy lệnh là 127. Hãy dựa vào các giá trị này khi kiểm tra mã thoát sau xargs trong script shell.

ℹ️ 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á.

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Prove your humanity: 2   +   3   =