Xargs: nhiều cách sử dụng. Sử dụng chuỗi thoát để nhập một chuỗi dài. Tạo cây thư mục bằng một lệnh

Có một lệnh rất lạ trong Linux xargs , điều mà các bậc thầy rất yêu thích nhưng lại không vội giải thích cách thức hoạt động của nó. Internet có rất nhiều công thức về “cách sử dụng xargs”, nhưng không có công thức nào nêu rõ điều quan trọng nhất: lệnh này thực sự làm gì.

Điều quan trọng nhất

TRONG phác thảo chungĐiều tương tự được viết ở mọi nơi: lệnh xargs lấy một luồng đầu vào (đó là lý do tại sao nó luôn được đặt trước một số lệnh và ký hiệu chuyển hướng luồng "|") và với một số cú pháp kỳ diệu sẽ thực thi lệnh được chỉ định trong đó.

Đây là những gì lệnh xargs thực sự làm.(Tôi sẽ cố gắng trình bày nó một cách khách quan nhất có thể). Nó phá vỡ dòng ký hiệu được gửi vào nó thành từng mảnh. Nó sử dụng các ký tự phân cách để phân chia luồng. Và đối với mỗi phần được chọn, nó sẽ thực thi lệnh được chỉ định ở phía bên phải, bổ sung lệnh này ở bên phải bằng các ký hiệu của phần được tìm thấy.

Đúng, định nghĩa này sử dụng khái niệm “đúng” hai lần. Các chi tiết được giải thích dưới đây. Trong thời gian chờ đợi, tốt hơn hết bạn nên xem cấu trúc của lệnh xargs dưới dạng hình ảnh. Về mặt cú pháp, lệnh xargs bao gồm hai phần - trái và phải:

Hơn nữa, có sự tách biệt rõ ràng về mặt hình ảnh giữa nơi còn lại và nơi phần bên phải, đơn giản là không. Nếu bạn đang cố gắng hiểu lệnh xargs của người khác, bạn cần phải tự mình tìm thấy "giao diện" này. Dưới đây là một số ví dụ:

Đủ thành viên

Bên trái

Phần bên phải

Ghi chú

xargs rm -rf

xargs

rm -rf

xargs -0 rm -rf

xargs -0

rm -rf

xargs -p -l gzip

xargs -p -l

gzip

xargs tar -zcf pl.tar.gz

xargs

tar -zcf pl.tar.gz

xargs -n2 fmv

xargs -n2

xargs -Tôi tập tin mv

xargs -Tôi tập tin

Vâng, không có sai sót nào ở đây

nhiệt độ xargs chown

xargs

nhiệt độ chown

xargs giết -9

xargs

giết -9

xargs -p vim

xargs -p

Nghĩa là, quy tắc được áp dụng ở đây: nếu sau xargs có các ký tự đứng trước dấu trừ"-" , thì đây là các tùy chọn lệnh xargs . Ngay khi có những ký hiệu không có dấu trừ thì đây đã là những ký hiệu ở phía bên phải. Nhưng bạn cần phải tính đến một số tùy chọn xargs yêu cầu một số dữ liệu khác theo sau chúng mà không có dấu trừ đứng trước (xem ví dụ với tùy chọn-TÔI ).

Và bây giờ là điều quan trọng nhất: nó thực thi lệnh gì? xargs ? Cô ấy đẩy gói ký hiệu mà cô ấy đã tách khỏi luồng đầu vào vào đâu? Thật đơn giản: cô ấy đặt những ký hiệu này ở bên phải của lệnh được viết ở phía bên phải. Tôi hiểu rằng khái niệm “quyền” được sử dụng hai lần ở đây. Sau đây là hình ảnh đặt mọi thứ vào đúng vị trí của nó:

Hãy lấy ví dụ cụ thể. Thư mục chứa các tập tin sau:

chính.cpp

chính.h

phiên bản.cpp

phiên bản.h

config.cpp

cấu hình.h

dữ liệu.cpp

dữ liệu.h

Trong thư mục này lệnh được thực thi:

$ tìm. -name "*.cpp" | xargs -n 1 rm -rf

Xargs sẽ tạo ra những lệnh nào? Để trả lời câu hỏi này, bạn cần hiểu những gì sẽ được đưa vào đầu vào của nó. Và đầu vào sẽ là kết quả của lệnh find:

./main.cpp

./version.cpp

./config.cpp

./data.cpp

Lệnh xargs xem xét dấu phân cách dấu cách, tab hoặc nguồn cấp dữ liệu dòng (và trình tự liên tục của chúng). Do đó, bốn lệnh sẽ được thực thi cuối cùng:

rm -rf ./main.cpp

rm -rf ./version.cpp

rm -rf ./config.cpp

rm -rf ./data.cpp

Rất lưu ý quan trọng về lựa chọn kỳ diệu

Có một lưu ý rất quan trọng. Nếu bạn không hiểu nó, bạn sẽ không thể làm việc bình thường với xargs và bạn sẽ giống như tác giả của những bài báo nghĩ rằng họ hiểu cách hoạt động của xargs, nhưng thực tế lại viết những điều vô nghĩa khủng khiếp. Trong ví dụ trên, tùy chọn được viết vì một lý do"-n 1".

Tùy chọn "-n 1" khiến xargs thực thi lệnh cho từng đoạn liên tiếp từ luồng đầu vào. Vâng, tôi hiểu rằng điều này nghe có vẻ điên rồ: xét cho cùng, nhóm xargs phải làm chính xác điều đó! Rốt cuộc, hướng dẫn sử dụng nói như sau:"xargs đọc các mục từ đầu vào tiêu chuẩn, được phân cách bằng khoảng trống (có thể được bảo vệ bằng dấu ngoặc kép hoặc dấu ngoặc đơn hoặc dấu gạch chéo ngược) hoặc dòng mới và thực thi lệnh (mặc định là/bin/echo) một hoặc nhiều lần với bất kỳ đối số ban đầu nào theo sau là các mục được đọc từ đầu vào tiêu chuẩn."Vấn đề là theo mặc định, nếu bạn không chỉ định"-n 1" , xargs coi toàn bộ luồng đến, được chia theo dấu cách, tab và ngắt dòng, dưới dạng MỘT đối số. Và trên thực tế, toàn bộ luồng đến chỉ được thay thế bằng lệnh đang được thực thi. Thật là một bất ngờ từ các nhà phát triển!

Câu hỏi: Vậy thì các ví dụ đưa ra trong bài viết hoạt động như thế nào, chẳng hạn như

$ tìm. -name "*.cpp" | xargs rm -rf

$ tìm. -name "*.cpp" | xargs wc -l

Và chúng hoạt động đơn giản vì chính các lệnh rm, wc và những thứ khác giống như chúng có thể hoạt động với một tập hợp tên tệp. Và người dùng lầm tưởng rằng đây là xargs Gọi các lệnh này nhiều lần cho mỗi tên tệp. Và để đảm bảo điều này, bạn có thể sử dụng tùy chọn-t (in lệnh được tạo xargs , trước khi thực hiện nó). Nhưng để xem kết quả, bạn vẫn cần sử dụng cấu trúc chuyển hướng đầu ra từ luồng lỗi 2>&1 (vì sử dụng tùy chọn-t cung cấp đầu ra cho một luồng lỗi thay vì cho bảng điều khiển tiêu chuẩn). Và đây là những gì bạn có thể thấy.

Nếu bạn viết lệnh xargs không có tùy chọn "-n 1" , thì điều sau sẽ xảy ra:

$ tìm. -name "*.cpp" | xargs -t rm -rf 2>&1

rm -rf ./main.cpp ./version.cpp ./config.cpp ./data.cpp

Có thể thấy chỉ có một đội tình nguyện rm và một danh sách tên tệp được truyền cho nó. Chỉ là kết quả công việc của nó sẽ trông như thể nó được gọi riêng cho từng tệp.

Nếu bạn sử dụng tùy chọn"-n 1" , khi đó hình ảnh sẽ khác:

$ tìm. -name "*.cpp" | xargs-n 1 -t rm -rf 2>&1

rm -rf ./main.cpp

rm -rf ./version.cpp

rm -rf ./config.cpp

rm -rf ./data.cpp

Ở đây hành vi đúng như đã hứa. Hãy nhớ tùy chọn này và đừng ngạc nhiên rằng xargs hoạt động có phần sai nếu bạn không sử dụng tùy chọn này. Cũng nên nhớ rằng trong nhiều bài viết trên Internet, các lệnh có xargs đơn giản là không thể hoạt động được. Các tác giả nghĩ rằng họ biết kết quả sẽ như thế nào và thậm chí không kiểm tra phần "rõ ràng", do đó, người dùng chưa chuẩn bị quyết định lặp lại những gì được viết trong bài viết sẽ không thực sự hiểu bất cứ điều gì.

Có một điểm tinh tế hơn. xargs có giới hạn về độ dài của luồng đầu vào. Và nếu luồng đầu vào quá lớn, xargs sẽ chia nó thành hai hoặc nhiều phần và đối với mỗi phần, nó vẫn sẽ gọi một lệnh riêng được chỉ định ở phía bên phải. Để tránh những tình huống không lường trước được như vậy, hãy sử dụng tùy chọn"-n 1".

lệnh xargs không có đối số

Đôi khi bạn có thể bắt gặp một công trình gây nản lòng như:

tr -dc A-Za-z0-9_< /dev/urandom | head -c 10 | xargs

Lệnh này tạo ra mật khẩu ngẫu nhiên dài 10 ký tự. Nhưng lệnh có nghĩa là gì? xargs không có đối số ở cuối lệnh này?

Đáp án đơn giản. Đội xargs không có đối số, thực sự nghĩ rằng lệnh ở phía bên phải của nó là/bin/echo . Và chuyển luồng đến thông qua lệnh tiếng vọng . Tại sao điều này là cần thiết? TRONG trong ví dụ nàyđiều này chỉ đơn giản là để đảm bảo rằng kết quả cuối cùng kết thúc bằng ký tự dòng mới. Đây là một ví dụ cho thấy sự khác biệt giữa một đội không có xargs là xargs :

> tr -dc A-Za-z0-9_< /dev/urandom | head -c 10

7jk2qx4cX8>

> tr -dc A-Za-z0-9_< /dev/urandom | head -c 10 | xargs

zSlr2HsbSa

Dấu cách trong tên tệp

Vì xargs coi dấu cách, tab và dòng mới là dấu phân cách nên sẽ xảy ra sự cố khi xử lý tên tệp chứa ký tự khoảng trắng.

Thông thường, tên tệp đầu vào cho chương trình xargs được cung cấp từ kết quả của lệnh. tìm thấy . Và để giải quyết vấn đề này nhóm tìm có tùy chọn "-print0" . Nó thay thế ngắt dòng bằng ký tự null\x0 . Và lệnh xargs có tùy chọn "-0" (trừ 0), với sự trợ giúp của luồng đầu vào được chia thành các phần được phân tách bằng ký hiệu\x0 .

Giả sử một tập tin xuất hiện trong một thư mục có tên"tập tin mới.cpp" . Nếu bạn không sử dụng các tùy chọn chuyển đổi null thành null, điều sau sẽ xảy ra:

$ tìm. -name "*.cpp" | xargs -n 1 -t rm -rf 2>&1

rm -rf ./mới

rm -rf tập tin.cpp

và tất nhiên là tập tin"tập tin mới.cpp" sẽ không bị xóa. Nếu bạn thêm các tùy chọn trên, lệnh sẽ hoạt động chính xác:

$ tìm. -name "*.cpp" -print0 | xargs -n 1 -t -0 rm -rf 2>&1

rm -rf ./file mới.cpp

và tập tin sẽ bị xóa.

Điều gì xảy ra nếu bạn không viết tùy chọn "-n"?

Xin lưu ý rằng các lệnh trên sử dụng tùy chọn"-n 1" . Điều gì sẽ xảy ra nếu bạn không viết nó? Về nguyên tắc, mọi thứ sẽ hoạt động giống hệt nhau. Nhưng ít người có thể giải thích cách thức hoạt động của nó, vì về mặt trực quan, các lệnh sẽ giống nhau nhưng kết quả sẽ khác. Đây là một ví dụ.

Lệnh không có tùy chọn "-n 1" và không có tùy chọn chuyển đổi null:

$ tìm. -name "*.cpp" | xargs -t rm -rf 2>&1

"Ừm..." , và nó sẽ không xóa tập tin"tệp mới.cpp" .

Và bây giờ lệnh không có tùy chọn "-n 1", nhưng có các tùy chọn chuyển đổi ký tự null:

$ tìm. -name "*.cpp" -print0 | xargs -t -0 rm -rf 2>&1

rm -rf ./main.cpp ./data.cpp ./config.cpp ./version.cpp ./new file.cpp

Kết quả là đội đã được xây dựng"Ừm..." , bề ngoài hoàn toàn giống với cái trước, nhưng nó sẽ xóa tập tin "file.cpp mới"!

Thật khó để giải thích cách thức hoạt động của nó. Rốt cuộc, tùy chọn"-0" là lệnh xargs, không phải lệnh rm . Trong trang lệnh man rm Không có dấu hiệu nào cho thấy nếu tên tệp được phân tách bằng ký tự null thì các ký tự khoảng trắng trong tên tệp sẽ được coi là ký tự chữ chứ không phải là dấu phân cách. Đối với tác giả bài báo, hành vi này vẫn còn là một bí ẩn và cho đến nay vẫn chưa có chuyên gia nào có thể giải thích được điều gì đang thực sự xảy ra.

Câu hỏi quan trọng nhất

Nhưng làm cách nào để tạo các lệnh mà bạn không chỉ cần thêm chuỗi ký tự tìm thấy vào bên phải? Và nếu bạn cần thêm cái gì khác sau giá trị được chèn vào bên phải? Tôi nên làm gì? Nhưng không thể nào! Đây là câu trả lời. Không thể xây dựng một lệnh tùy ý bằng xargs. Bạn chỉ có thể xây dựng một lệnh bao gồm phần cơ sở (cố định) và phần bên phải (ký tự đại diện). Đó là tất cả!

Nếu xargs cho phép bạn thêm nội dung nào đó sau phần ký tự đại diện thì cuộc sống với lệnh này sẽ dễ dàng hơn nhiều. Ví dụ: có thể đặt dấu ngoặc kép trước và sau phần ký tự đại diện và đơn giản là không có vấn đề gì với khoảng trắng trong tên tệp. Nhưng cú pháp xargs không cho phép hành vi như vậy.

Vì vậy, thực sự không thể xây dựng lệnh được yêu cầu trong *NIX? Tất nhiên là có sẵn. Đối với điều này bạn có thể sử dụng lệnh awk và cô ấy chức năng hệ thống(). Làm thế nào để làm điều này được viết trong bài viết: .

Gần đây tôi đã có cảm hứng để viết bài đăng này sau khi gặp phải tình huống cần chỉnh sửa một số tệp trong một dự án và thay thế một số từ bằng những từ khác. Tôi đã từng làm điều này thông qua Sổ tay++(CTRL + H), nhưng điều này sẽ tốt nếu chúng ta biết chúng ta cần thay thế từ đó trong tệp nào và liệu có hàng nghìn tệp này hay không. Vì vậy tôi muốn giới thiệu với bạn 3 Công cụ cơ bản hệ thống UNIX cho đến nay: grep, xargs, Và sed.

Có thể bạn đã từng nghe đến chúng trước đây và đã biết cách sử dụng chúng, nhưng có thể bạn sẽ không học được điều gì mới. Nhưng nếu bạn muốn tìm hiểu những điều cơ bản về cách sử dụng những công cụ này, hãy đọc tiếp.

Grep

Grep là một dòng lệnh Unix cơ bản để tìm kiếm các cụm từ từ cả luồng và tệp tiêu chuẩn. Grep trả về thông tin về các tệp chứa cụm từ của bạn và một ít thông tin về vị trí của chúng. Đây là một ví dụ phương pháp chuẩn sử dụng Grep:

Grep "chân trang" index.html

Bây giờ hãy thêm một số tùy chọn tìm kiếm:

  • Tôi- Bỏ qua các trường hợp khi so sánh.
  • N- Hiển thị trước mỗi dòng số của nó trong file.
  • b- Hiển thị số cột trong file tìm thấy.
grep -i -n -b "chân trang" index.html

Bây giờ tìm kiếm toàn bộ từ:

  • w- Tìm kiếm bằng cách sử dụng toàn bộ từ. Ví dụ: khi tìm kiếm một chuỗi thông thường văn bản grep có thể tìm thấy từ textarea. Và nếu sử dụng chìa khóa đã cho thì chỉ những dòng chứa văn bản từ mới được tìm thấy.
grep -w "văn bản" index.html

Tìm kiếm theo tệp là tốt, nhưng sẽ tốt hơn nếu chúng ta có thể tìm kiếm tệp theo cách đệ quy trong dự án.

  • r- Tìm kiếm đệ quy các tập tin từ thư mục hiện tại.
  • tôi- Chỉ trả về tên file chứa giá trị tìm kiếm.
grep -r -l "chân trang" ./

Bây giờ hãy thử hiển thị các tệp không chứa giá trị mong muốn.

  • L- Hiển thị tên file không chứa giá trị mong muốn.
grep -r -L -i "chân trang" ./

Ngoài ra, chúng ta cũng thường xuyên phải xem xét các loại cụ thể các tập tin có giá trị nhất định.

  • –include=“MẪU”- Tìm kiếm trong tập tin bằng cách sử dụng một mẫu nhất định
grep -r --include="*.html" -l "chân trang" ./

Tìm kiếm các tệp bắt đầu bằng chỉ mục và kết thúc bằng .php

Grep -r --include="index*.php" -l "footer" ./

Bây giờ hãy chuyển kết quả công việc vào một tập tin.

Grep -r -l "chân trang" ./ > out.txt

Xarg

Lệnh tuyệt vời này hoạt động trên một đoạn giới thiệu, lấy dữ liệu từ đầu vào tiêu chuẩn hoặc từ một tệp, phân chia nó theo thông số quy định và sau đó chuyển nó sang chương trình khác làm đối số. Xargs được thực thi cho đến khi hết dữ liệu từ luồng. Bây giờ chúng ta hãy xem xét một số ví dụ đơn giản.

Chia luồng tiêu chuẩn thành các đối số.

  • -N- Xác định số lượng đối số trả về.
vang 1 2 3 4 | xargs -n 1

Bây giờ hãy đặt dấu phân cách đối số.

  • –d- Trỏ tới dấu phân cách để xuất đối số.
tiếng vang "1-2-3-4" | xargs -d "-" -n 1

Đây là nhiều hơn nữa ví dụ thú vị trong đó xargs được sử dụng để truyền các tập tin cần xóa.

Tìm thấy. -name "*.txt"| xargs rm -rf

Toàn bộ các điểm sử dụng xargsĐây là sự phân chia các đối số đến để truyền các đối số tiếp theo tới các chương trình khác.

Sed

Sed là trình chỉnh sửa luồng lấy văn bản từ luồng tiêu chuẩn hoặc từ tệp văn bản, thực hiện một số thao tác trên chuỗi và sau đó xuất kết quả sang đầu ra tiêu chuẩn hoặc vào một tập tin. Thông thường trong các tập lệnh, sed được sử dụng trong quy trình xử lý dữ liệu, kết hợp với các lệnh và tiện ích khác.

Chúng ta hãy làm thay thế đơn giản dòng từ tệp text.txt và lưu nó vào tệp out.txt.

Sed "s/text/test/g" text.txt > out.txt

Bây giờ hãy lưu tất cả các thay đổi vào tệp hiện tại.

  • Tôi- để ghi các thay đổi vào tập tin hiện tại.
sed -i "s/text/test/g" text.txt

Hãy kết hợp mọi thứ lại với nhau

Bằng cách kết hợp ba lệnh chung này cho tất cả hệ thống unix, chúng ta có thể tạo một tập lệnh thay thế văn bản khá mạnh mẽ. Hầu hết hành động đều đến từ việc sử dụng lệnh sed, nhưng các lệnh khác rất hữu ích cho việc xây dựng truy vấn. Bây giờ hãy xem một ví dụ về việc sử dụng cả ba chương trình quét:

Grep -r -l "foo" ./ | xargs sed -i "s/foo/bar/g"

Bằng cách này chúng tôi có thể thay thế mọi thứ foo TRÊN quán ba sử dụng sự kết hợp đơn giản từ các chương trình này.

Bây giờ chúng ta đã tìm hiểu kiến ​​thức cơ bản về các công cụ tuyệt vời như grep, xargs và sed. Chúng tôi sẽ có thể viết các tập lệnh nâng cao hơn cho các nhiệm vụ của mình.

Rất nhiều điều đã được viết về tiện ích xargs - còn có thể viết gì thêm nữa? Nhưng, như họ nói, nếu bạn tìm hiểu sâu hơn, thì hóa ra nhiều ấn phẩm chỉ phác thảo những điều cơ bản nhất mà thiếu điều chính: chúng không giải thích cách sử dụng xargs trong thực tế thực tế. Bài viết phân tích những ứng dụng phức tạp và không hề nhỏ của điều này rất hữu ích quản trị hệ thống Thật không may, có rất ít công cụ. Đó là lý do tại sao chúng tôi viết bài này và cố gắng đưa vào đó nhiều ví dụ về cách sử dụng xargs để giải quyết nhiều vấn đề khác nhau.

Đầu tiên, chúng ta sẽ xem cách xargs hoạt động và phân tích các ví dụ đơn giản hơn, sau đó chuyển sang phân tích các trường hợp phức tạp và thú vị.

Chúng ta hãy nhớ những điều cơ bản

Cách thức hoạt động của xargs có thể được mô tả như sau: một chương trình lấy dữ liệu từ đầu vào tiêu chuẩn hoặc từ một tệp, chia nhỏ dữ liệu theo các tham số đã chỉ định và sau đó chuyển nó sang chương trình khác làm đối số.

TRONG nhìn chung Cú pháp lệnh xargs có thể được biểu diễn như sau:

[list_generator_command] | xargs [xargs_options] [lệnh]
Hãy xem cách tất cả hoạt động bằng cách sử dụng các ví dụ đơn giản và có tính sách giáo khoa.

Xóa tập tin

Một trong những tình huống phổ biến nhất mà xargs được sử dụng là xóa các tệp được tìm thấy bằng lệnh find.

Hãy tưởng tượng tình huống sau: có một thư mục trong đó một số lượng lớn các tập tin. Bạn cần xóa các tệp thuộc một loại nhất định khỏi nó (trong ví dụ của chúng tôi là các tệp có phần mở rộng *.sh). Để thực hiện thao tác này, bạn cần chuyển đầu ra của lệnh find cho xargs và lệnh -rm sẽ được áp dụng cho các tệp có phần mở rộng được chỉ định:

$ ls one.sh one.py two.sh two.py $ find . -name "*.sh"| xargs rm -rf $ ls one.py two.py

Lưu ý rằng thao tác xóa tệp có thể được thực hiện mà không cần xargs mà sử dụng lệnh

$ tìm. -name "*.sh" -exec rm -rf "()" \

Phương pháp được mô tả sẽ không hoạt động nếu tên của một trong các tệp cần xóa có khoảng trắng. Tên bao gồm hai từ cách nhau bởi dấu cách sẽ không được chấp nhận dưới dạng một tên duy nhất.

Hãy minh họa điều này bằng ví dụ sau:

$ ls file mới.sh one.sh one.py two.sh two.py $ find . -name "*.sh"| xargs rm -rf $ ls tệp mới.sh one.py two.py

Như bạn có thể thấy, tệp có khoảng trắng trong tên của nó không bị xóa.

Để giải quyết vấn đề này, hãy sử dụng tùy chọn print0 cho lệnh find và tùy chọn -0 cho lệnh xargs. Nó thay thế dấu phân cách tiêu chuẩn (ngắt dòng bằng ký tự null (\x0), có nghĩa là kết thúc chuỗi được lưu trữ:

$ tìm. -name "*.sh" -print0 | xargs -0 rm -rf

Xargs cũng có thể giúp, chẳng hạn như nhanh chóng xóa mọi thứ Hồ sơ tạm thờiđang có tiện ích mở rộng tmp:

$ tìm /tmp -name "*.tmp"| xargs rm

Nén tập tin

Bạn có thể nén tất cả các tệp trong thư mục hiện tại bằng gzip bằng cách nhập lệnh sau:

$ls | xargs -p -l gzip

Hãy xem một ví dụ khác: nén tất cả các tệp có phần mở rộng *.pl bằng tar:

$ tìm. -name "*.pl" | xargs tar -zcf pl.tar.gz

Đổi tên tập tin

Với xargs bạn có thể làm đổi tên hàng loạt các tập tin. Hãy tưởng tượng rằng chúng ta có một nhóm tệp có phần mở rộng *.txt và chúng ta cần thay thế phần mở rộng này bằng *.sql. Điều này có thể được thực hiện bằng cách sử dụng xargs và phát trực tuyến soạn thảo văn bản sed:

$ls | sed -e "p;s/.txt$/.sql/" | xargs -n2 fmv

Kết quả của việc thực thi nó, một danh sách các tệp được đổi tên sẽ được hiển thị trên bảng điều khiển.

Với xargs bạn cũng có thể thêm vào yếu tố bổ sung vào tên tệp (ví dụ: ngày):

$ls | xargs -I FILE mv()<...>-{}

Thay vì<..>bạn có thể thay thế bất cứ điều gì bạn muốn.
Dấu ngoặc nhọn () trong ví dụ này có nghĩa là "đối số hiện tại" (tức là tên tệp hiện tại).

Thay đổi quyền cho thư mục và tập tin

Sử dụng xargs bạn cũng có thể tăng tốc quá trình thay đổi quyền trên các tệp và thư mục cho người dùng cụ thể hoặc các nhóm. Giả sử chúng ta cần tìm tất cả các thư mục người dùng root và thay thế chủ sở hữu của họ bằng temp. Thao tác này được thực hiện bằng lệnh:

$ tìm. -nhóm gốc -print | nhiệt độ xargs chown

Để tìm tất cả các thư mục của nhóm gốc và thay thế nhóm bằng temp, hãy sử dụng lệnh:

$ tìm. -nhóm gốc -print | nhiệt độ xargs chgrp

Xargs và find: các hoạt động phức tạp

Bạn có thể thực hiện các thao tác phức tạp hơn bằng cách sử dụng lệnh find và xargs. Ví dụ: đây là cách bạn có thể xóa các tệp tạm thời được tạo cách đây hơn 7 ngày:

$ find /tmp -type f -name "*" -mtime +7 -print0 | xargs -0 rm -f

Và đây là cách dừng mạnh mẽ các tiến trình đã chạy hơn 7 ngày:

$ find /proc -user myuser -maxdeep 1 -type d -mtime +7 -exec basename() \; | xargs giết -9

Xargs và cắt

Xargs thường được sử dụng kết hợp với lệnh cut, cho phép bạn cắt các đường từ tập tin văn bản. Chúng ta hãy nhìn vào một số ví dụ thực tế. Sử dụng lệnh bên dưới, danh sách tất cả người dùng trên hệ thống sẽ được hiển thị trên bảng điều khiển:

$ cắt -d: -f1< /etc/passwd | sort | xargs echo

Và đội trông

Tệp * | grep ASCII | cắt -d:" -f1 | xargs -p vim
sẽ tuần tự mở các tệp để chỉnh sửa trong vim.
Hãy chú ý đến tùy chọn -p. Nhờ đó, lệnh sẽ được thực thi ở chế độ tương tác: xác nhận (y/n) sẽ được yêu cầu trước khi mở mỗi tệp.

Để kết luận, chúng tôi đưa ra một ví dụ phức tạp và thú vị khác - tìm kiếm đệ quy các tệp của size lớn trong một số thư mục:

$ tìm. -type f -printf "%20s %p\n" | sắp xếp -n | cắt -b22- | tr "\n" "\000" | xargs -0 ls -laSr

Chạy song song các tiến trình

Xargs thường được sử dụng cho phóng song song một số quy trình. Ví dụ: đây là cách bạn có thể nén đồng thời nhiều thư mục vào tar.gz:

$ echo dir1 dir2 dir3 | xargs -P 3 -I TÊN tar czf NAME.tar.gz TÊN

Ví dụ bên dưới sử dụng khóa chuyển -P. Anh ấy chỉ số tiền tối đa các tiến trình sẽ chạy đồng thời. Giả sử rằng chúng ta có 10 đối số làm đầu vào. Nếu chúng ta nhập lệnh xargs bằng khóa chuyển -P 3 thì 3 phiên bản của lệnh sau xargs sẽ được khởi chạy, với mỗi đối số này.

Với xargs, bạn cũng có thể tải xuống song song nhiều tệp từ Internet:

Trong ví dụ đã cho với địa chỉ được chỉ định tất cả sẽ được tải xuống tập tin đồ họa Với phần mở rộng jpg; Công tắc -P cho biết bạn cần tải xuống 10 tệp cùng một lúc.

Kết quả kỳ thi vào trường

Hãy tóm tắt các kết quả sơ bộ và xây dựng một số quy tắc làm việc với xargs.

  1. Xargs không hoạt động với các tệp có khoảng trắng trong tên của chúng. Để giải quyết vấn đề này bằng lệnh xargs, hãy sử dụng tùy chọn −0. Bạn cũng có thể bỏ qua khoảng trắng trong tên tệp như sau:
    $ xargs -I FILE my_command “FILE”
  2. Lệnh xargs chấp nhận các lệnh từ đầu vào tiêu chuẩn, được phân tách bằng dấu cách hoặc dòng mới. Để nhóm các lệnh này bạn có thể sử dụng double hoặc dấu nháy đơn. Bạn cũng có thể chỉ định dấu phân cách bằng tùy chọn -d;
  3. Nếu không có đối số nào được truyền cho xargs, lệnh /bin/echo sẽ được thực thi theo mặc định;
  4. Trong nhiều trường hợp, lệnh xargs có thể được thay thế bằng vòng lặp for. Ví dụ, lệnh
    $ tìm. -type f -and -iname "*.deb" | xargs -n 1 dpkg -I
    hoàn toàn tương đương với chu trình
    $ cho tệp trong `find . -type f -and -iname "*.deb"`; làm dpkg -I "$file"; xong

Những ví dụ không tầm thường

Chúng ta đã nhớ những điều cơ bản, chúng ta đã xem xét các trường hợp sử dụng điển hình... Bây giờ hãy chuyển sang các ví dụ phức tạp hơn và không tầm thường. Chúng tôi đã tự mình nghĩ ra một số trong số chúng khi làm việc trên Công việc hàng ngày và một số được lấy từ trang web http://www.commandlinefu.com (chúng tôi thực sự khuyên bất kỳ ai muốn tìm hiểu sự phức tạp khi làm việc với dòng lệnh thỉnh thoảng hãy truy cập trang này - ở đó đôi khi bạn có thể tìm thấy rất nhiều lời khuyên hữu ích).

Cấm địa chỉ IP khỏi danh sách

Để cấm địa chỉ IP khỏi danh sách, bạn cần thêm chúng vào bảng IP bằng quy tắc DROP. Thao tác này được thực hiện bằng lệnh:

$ mèo bad_ip_list | xargs -I IP iptables -A INPUT -s IP -j DROP
Bạn cũng có thể thực hiện một thao tác phức tạp hơn và cấm tất cả các địa chỉ bằng AS:

$ /usr/bin/whois -H -h whois.ripe.net -T Route -i Origin AS<номер>|egrep "^route"|awk "(print $2)" |xargs -I NET iptables -A INPUT -s NET -j DROP

Thay đổi định dạng URL

Bạn có thể chuyển đổi một URL như “http%3A%2F%2Fwww.google.com” thành “www ,google.com” bằng lệnh:

Echo "http%3A%2F%2Fwww.google.com" | sed -e"s/%\(\)/\\\\\x\1/g" | xargs echo -e

Tạo mật khẩu 10 ký tự

Phát ra mật khẩu mạnh có thể được thực hiện bằng cách sử dụng lệnh như:

$ tr -dc A-Za-z0-9_< /dev/urandom | head -c 10 | xargs

Bạn có thể tạo mật khẩu mà không cần sự trợ giúp của xargs: có một tiện ích chuyên dụng cho việc này, pwgen. Một số phương pháp tạo mật khẩu khác cũng được mô tả.

Tìm kiếm các tệp nhị phân được cài đặt mà không sử dụng dpkg

Một hoạt động như vậy có thể được yêu cầu nếu, ví dụ, chiếc xe đã trở thành nạn nhân tin tặc tấn công và phần mềm độc hại đã được cài đặt trên đó phần mềm. Nó sẽ giúp xác định những chương trình mà kẻ tấn công đã cài đặt. lệnh tiếp theo(nó tìm cách chạy các "nhị phân" được cài đặt mà không cần sử dụng trình quản lý gói dpkg):

$ cat /var/lib/dpkg/info/*.list > /tmp/listin ; ls /proc/*/exe |xargs -l readlink | grep -xvFf /tmp/listin; rm /tmp/listin

Loại bỏ các gói kernel lỗi thời

$ dpkg -l linux-* | awk "/^ii/( print $2)" | grep -v -e `uname -r | cắt -f1,2 -d"-"` | grep -e | xargs sudo apt-get -y thanh lọc

Vấn đề loại bỏ các hạt nhân cũ đã được thảo luận trên Habré - xem (tại cùng một liên kết, bạn có thể tìm thấy các ví dụ thú vị về lệnh).

Chuyển đổi tập lệnh thành một chuỗi

Đôi khi có nhu cầu chuyển một đoạn script lớn thành một dòng. Bạn có thể làm như thế này: Thêm thẻ

Rất nhiều điều đã được viết về tiện ích xargs - còn có thể viết gì thêm nữa? Nhưng, như họ nói, nếu bạn tìm hiểu sâu hơn, thì hóa ra nhiều ấn phẩm chỉ phác thảo những điều cơ bản nhất mà thiếu điều chính: chúng không giải thích cách sử dụng xargs trong thực tế thực tế. Thật không may, có rất ít bài viết phân tích các tùy chọn phức tạp và không tầm thường để sử dụng công cụ này, điều này rất hữu ích cho quản trị viên hệ thống. Đó là lý do tại sao chúng tôi viết bài viết của mình và cố gắng đưa ra càng nhiều ví dụ về cách sử dụng xargs để giải quyết các vấn đề khác nhau càng tốt.

Đầu tiên, chúng ta sẽ xem cách xargs hoạt động và phân tích các ví dụ đơn giản hơn, sau đó chuyển sang phân tích các trường hợp phức tạp và thú vị.

Chúng ta hãy nhớ những điều cơ bản

Cách thức hoạt động của xargs có thể được mô tả như sau: một chương trình lấy dữ liệu từ đầu vào tiêu chuẩn hoặc từ một tệp, chia nhỏ dữ liệu theo các tham số đã chỉ định và sau đó chuyển nó sang chương trình khác làm đối số.

Nói chung, cú pháp của lệnh xargs có thể được biểu diễn như sau:

[list_generator_command] | xargs [xargs_options] [lệnh]

Hãy xem cách tất cả hoạt động bằng cách sử dụng các ví dụ đơn giản và có tính sách giáo khoa.

Xóa tập tin

Một trong những tình huống phổ biến nhất mà xargs được sử dụng là xóa các tệp được tìm thấy bằng lệnh find.

Hãy tưởng tượng tình huống sau: có một thư mục chứa một số lượng lớn tệp. Bạn cần xóa các tệp thuộc một loại nhất định khỏi nó (trong ví dụ của chúng tôi là các tệp có phần mở rộng *.sh). Để thực hiện thao tác này, bạn cần chuyển đầu ra của lệnh find cho xargs và lệnh -rm sẽ được áp dụng cho các tệp có phần mở rộng được chỉ định:

$ ls one.sh one.py two.sh two.py $ find . -name "*.sh"| xargs rm -rf $ ls one.py two.py

Lưu ý rằng thao tác xóa tệp có thể được thực hiện mà không cần xargs mà sử dụng lệnh

$ tìm. -name "*.sh" -exec rm -rf "()" \

Phương pháp được mô tả sẽ không hoạt động nếu tên của một trong các tệp cần xóa có khoảng trắng. Tên bao gồm hai từ cách nhau bởi dấu cách sẽ không được chấp nhận dưới dạng một tên duy nhất.

Hãy minh họa điều này bằng ví dụ sau:

$ ls file mới.sh one.sh one.py two.sh two.py $ find . -name "*.sh"| xargs rm -rf $ ls tệp mới.sh one.py two.py

Như bạn có thể thấy, tệp có khoảng trắng trong tên của nó không bị xóa.

Để giải quyết vấn đề này, hãy sử dụng tùy chọn print0 cho lệnh find và tùy chọn -0 cho lệnh xargs. Nó thay thế dấu phân cách tiêu chuẩn (ngắt dòng bằng ký tự null (\x0), có nghĩa là kết thúc chuỗi được lưu trữ:

$ tìm. -name "*.sh" -print0 | xargs -0 rm -rf

Xargs cũng có thể giúp, chẳng hạn như xóa nhanh tất cả các tệp tạm thời có phần mở rộng tmp:

$ tìm /tmp -name "*.tmp"| xargs rm

Nén tập tin

Bạn có thể nén tất cả các tệp trong thư mục hiện tại bằng gzip bằng cách nhập lệnh sau:

$ls | xargs -p -l gzip

Hãy xem một ví dụ khác: nén tất cả các tệp có phần mở rộng *.pl bằng tar:

$ tìm. -name "*.pl" | xargs tar -zcf pl.tar.gz

Đổi tên tập tin

Sử dụng xargs bạn có thể đổi tên hàng loạt tệp. Hãy tưởng tượng rằng chúng ta có một nhóm tệp có phần mở rộng *.txt và chúng ta cần thay thế phần mở rộng này bằng *.sql. Điều này có thể được thực hiện bằng cách sử dụng xargs và trình soạn thảo văn bản trực tuyến sed:

$ls | sed -e "p;s/.txt$/.sql/" | xargs -n2 fmv

Kết quả của việc thực thi nó, một danh sách các tệp được đổi tên sẽ được hiển thị trên bảng điều khiển.

Bạn cũng có thể sử dụng xargs để thêm các thành phần bổ sung vào tên tệp (chẳng hạn như ngày):

$ls | xargs -I FILE mv()<...>-{}

Thay vì<..>bạn có thể thay thế bất cứ điều gì bạn muốn.
Dấu ngoặc nhọn () trong ví dụ này có nghĩa là "đối số hiện tại" (tức là tên tệp hiện tại).

Thay đổi quyền cho thư mục và tập tin

Sử dụng xargs, bạn cũng có thể tăng tốc quá trình thay đổi quyền trên tệp và thư mục cho một người dùng hoặc nhóm cụ thể. Giả sử chúng ta cần tìm tất cả các thư mục người dùng root và thay đổi chủ sở hữu của chúng thành temp. Thao tác này được thực hiện bằng lệnh:

$ tìm. -nhóm gốc -print | nhiệt độ xargs chown

Để tìm tất cả các thư mục của nhóm gốc và thay thế nhóm bằng temp, hãy sử dụng lệnh:

$ tìm. -nhóm gốc -print | nhiệt độ xargs chgrp

Xargs và find: các hoạt động phức tạp

Bạn có thể thực hiện các thao tác phức tạp hơn bằng cách sử dụng lệnh find và xargs. Ví dụ: đây là cách bạn có thể xóa các tệp tạm thời được tạo cách đây hơn 7 ngày:

$ find /tmp -type f -name "*" -mtime +7 -print0 | xargs -0 rm -f

Và đây là cách dừng mạnh mẽ các tiến trình đã chạy hơn 7 ngày:

$ find /proc -user myuser -maxdeep 1 -type d -mtime +7 -exec basename() \; | xargs giết -9

Xargs và cắt

Xargs thường được sử dụng kết hợp với lệnh cắt, cho phép bạn cắt dòng khỏi tệp văn bản. Hãy xem xét một số ví dụ thực tế. Sử dụng lệnh bên dưới, danh sách tất cả người dùng trên hệ thống sẽ được hiển thị trên bảng điều khiển:

$ cắt -d: -f1< /etc/passwd | sort | xargs echo

Và đội trông

Tệp * | grep ASCII | cắt -d:" -f1 | xargs -p vim

sẽ tuần tự mở các tệp để chỉnh sửa trong vim.
Hãy chú ý đến tùy chọn -p. Nhờ đó, lệnh sẽ được thực thi ở chế độ tương tác: xác nhận (y/n) sẽ được yêu cầu trước khi mở mỗi tệp.

Tóm lại, đây là một ví dụ phức tạp và thú vị khác - tìm kiếm đệ quy các tệp lớn nhất trong một thư mục nhất định:

$ tìm. -type f -printf "%20s %p\n" | sắp xếp -n | cắt -b22- | tr "\n" "\000" | xargs -0 ls -laSr

Chạy song song các tiến trình

Xargs thường được sử dụng để chạy song song nhiều tiến trình. Ví dụ: đây là cách bạn có thể nén đồng thời nhiều thư mục vào tar.gz:

$ echo dir1 dir2 dir3 | xargs -P 3 -I TÊN tar czf NAME.tar.gz TÊN

Ví dụ bên dưới sử dụng khóa chuyển -P. Nó chỉ định số lượng tiến trình tối đa sẽ chạy đồng thời. Giả sử rằng chúng ta có 10 đối số làm đầu vào. Nếu chúng ta nhập lệnh xargs bằng khóa chuyển -P 3 thì 3 phiên bản của lệnh sau xargs sẽ được khởi chạy, với mỗi đối số này.

Với xargs, bạn cũng có thể tải xuống song song nhiều tệp từ Internet:

Trong ví dụ đã cho, tất cả các tệp đồ họa có phần mở rộng jpg sẽ được tải xuống từ địa chỉ đã chỉ định; Công tắc -P cho biết bạn cần tải xuống 10 tệp cùng một lúc.

Kết quả kỳ thi vào trường

Hãy tóm tắt các kết quả sơ bộ và xây dựng một số quy tắc làm việc với xargs.

  1. Xargs không hoạt động với các tệp có khoảng trắng trong tên của chúng. Để giải quyết vấn đề này bằng lệnh xargs, hãy sử dụng tùy chọn −0. Bạn cũng có thể bỏ qua khoảng trắng trong tên tệp như sau: $ xargs -I FILE my_command “FILE”
  2. Lệnh xargs chấp nhận các lệnh từ đầu vào tiêu chuẩn, được phân tách bằng dấu cách hoặc dòng mới. Để nhóm các lệnh này, bạn có thể sử dụng dấu ngoặc kép hoặc dấu ngoặc đơn. Bạn cũng có thể chỉ định dấu phân cách bằng tùy chọn -d;
  3. Nếu không có đối số nào được truyền cho xargs, lệnh /bin/echo sẽ được thực thi theo mặc định;
  4. Trong nhiều trường hợp, lệnh xargs có thể được thay thế bằng vòng lặp for. Ví dụ: lệnh $find. -type f -and -iname "*.deb" | xargs -n 1 dpkg -I

    hoàn toàn tương đương với chu trình

    $ cho tệp trong `find . -type f -and -iname "*.deb"`; làm dpkg -I "$file"; xong

Những ví dụ không tầm thường

Chúng ta đã nhớ những điều cơ bản, chúng ta đã xem xét các trường hợp sử dụng điển hình... Bây giờ hãy chuyển sang các ví dụ phức tạp hơn và không tầm thường. Chúng tôi đã tự mình nghĩ ra một số trong số chúng khi thực hiện các công việc hàng ngày và một số chúng tôi thu thập được từ trang web http://www.commandlinefu.com (chúng tôi thực sự khuyên tất cả những ai muốn tìm hiểu sự phức tạp khi làm việc với dòng lệnh thỉnh thoảng ghé thăm nó - ở đó đôi khi bạn có thể tìm thấy những lời khuyên rất hữu ích).

Cấm địa chỉ IP khỏi danh sách

Để cấm địa chỉ IP khỏi danh sách, bạn cần thêm chúng vào bảng IP bằng quy tắc DROP. Thao tác này được thực hiện bằng lệnh:

$ mèo bad_ip_list | xargs -I IP iptables -A INPUT -s IP -j DROP

Bạn cũng có thể thực hiện một thao tác phức tạp hơn và cấm tất cả các địa chỉ bằng AS:

$ /usr/bin/whois -H -h whois.ripe.net -T Route -i Origin AS<номер>|egrep "^route"|awk "(print $2)" |xargs -I NET iptables -A INPUT -s NET -j DROP

Thay đổi định dạng URL

Bạn có thể chuyển đổi một URL như “http%3A%2F%2Fwww.google.com” thành “http://www,google.com” bằng lệnh:

Echo "http%3A%2F%2Fwww.google.com" | sed -e"s/%\(\)/\\\\\x\1/g" | xargs echo -e

Tạo mật khẩu 10 ký tự

Bạn có thể tạo mật khẩu mạnh bằng lệnh như:

$ tr -dc A-Za-z0-9_< /dev/urandom | head -c 10 | xargs

Bạn có thể tạo mật khẩu mà không cần sự trợ giúp của xargs: có một tiện ích chuyên dụng cho việc này, pwgen. Một số phương pháp tạo mật khẩu khác cũng được mô tả.

Tìm kiếm các tệp nhị phân được cài đặt mà không sử dụng dpkg

Ví dụ: thao tác như vậy có thể được yêu cầu nếu máy là nạn nhân của một cuộc tấn công của hacker và phần mềm độc hại đã được cài đặt trên đó. Lệnh sau sẽ giúp bạn xác định những chương trình mà kẻ tấn công đã cài đặt (nó tìm kiếm các chương trình chạy "nhị phân" được cài đặt mà không sử dụng trình quản lý gói dpkg):

$ cat /var/lib/dpkg/info/*.list > /tmp/listin ; ls /proc/*/exe |xargs -l readlink | grep -xvFf /tmp/listin; rm /tmp/listin

Loại bỏ các gói kernel lỗi thời

$ dpkg -l linux-* | awk "/^ii/( print $2)" | grep -v -e `uname -r | cắt -f1,2 -d"-"` | grep -e | xargs sudo apt-get -y thanh lọc

Vấn đề loại bỏ các hạt nhân cũ đã được thảo luận trên Habré - xem (tại cùng một liên kết, bạn có thể tìm thấy các ví dụ thú vị về lệnh).

Chuyển đổi tập lệnh thành một chuỗi

Đôi khi có nhu cầu chuyển một đoạn script lớn thành một dòng. Bạn có thể làm điều đó như thế này:

$ (sed "s/#.*//g"|sed "/^ *$/d"|tr "\n" ";"|xargs echo)< script.sh

Phần kết luận

Như có thể thấy từ bài đánh giá, khả năng của xargs rộng hơn nhiều so với cái nhìn đầu tiên. Chúng tôi hy vọng rằng các ví dụ được đưa ra trong bài viết này sẽ hữu ích cho bạn. Nếu bạn biết người khác lựa chọn thú vị sử dụng xargs - chào mừng bạn đến nhận xét.

Vào những buổi tối mùa đông dài tôi ngồi và nghĩ “anh ấy sẽ đến thời gian ban ngày, Tôi sẽ ngồi xuống và tìm hiểu kỹ về tiện ích xarg bí ẩn này." Chà, có vẻ như đã đến lúc - tôi ngồi xuống để tìm hiểu. Điều đầu tiên khiến tôi chú ý là người đàn ông dành cho nó khá bí ẩn , và không làm sáng tỏ mọi thứ trong lần đầu tiên. Wikipedia cũng không thêm bất kỳ thông tin chi tiết nào, mà thậm chí còn khiến tôi bối rối, vì vậy tôi quyết định tiến hành điều tra của riêng mình và viết một cuốn sổ tay nhỏ về vấn đề này. Như bạn đã biết, miễn là bạn giải thích thì bạn tự hiểu :)

Vì vậy, xargs.

xargs là một tiện ích như vậy dòng lệnh, cho phép bạn gọi bất kỳ lệnh nào với các đối số được lấy từ đầu vào tiêu chuẩn. Hơn nữa, các đối số có thể được truyền cùng một lúc hoặc chúng có thể được nhóm thành nhiều phần. Chúng tôi sẽ nghiên cứu xargs phiên bản 4.4.0 và theo khuyến nghị của người đàn ông, chúng tôi sẽ chỉ sử dụng các đối số mới không được đánh dấu là không dùng nữa (tốt hơn là bạn nên làm quen ngay với cách hoạt động chính xác).

Vì vậy, điều đầu tiên cần hiểu là cách xargs xử lý luồng đến và chia nó thành các đối số. Có một số chế độ tùy thuộc vào các tùy chọn:

1. Bình thường. Theo mặc định, dấu phân tách đối số là bất kỳ ký tự khoảng trắng nào: dấu cách, tab, tab dọc hoặc dòng mới. Nhưng như trong vỏ lệnh bạn có thể sử dụng "" hoặc \ để ngăn chặn việc chia tách đối số.

2. Đều đặn, có nhóm. Chế độ được kích hoạt bởi tham số -L. Gần giống với cái trước, ngoại trừ xargs ghi nhớ đối số nào nằm trên dòng nào. Hơn nữa, nếu dòng kết thúc bằng dấu cách hoặc tab, hàng tiếp theođược coi là sự tiếp nối của hiện tại.

3. Từng dòng một. Được bật khi sử dụng tùy chọn -I hoặc -0. Trong trường hợp này, toàn bộ chuỗi được coi là toàn bộ đối số, mặc dù có khoảng trắng và tab bên trong. Đối với -I cuối dòng là ký tự "\n" và đối với -0 là ký tự "\0"

Chúng ta hãy làm một vài bài kiểm tra để hiểu rõ hơn về tất cả điều này. Hãy tạo một file test với nội dung sau (== không cần nhập vào file):
==
arg1
không gian arg2
"arg3 được trích dẫn"
arg4\ đã thoát
arg5 với
Tiếp tục
==
(Phải có khoảng trắng sau "arg5 with")
Và chúng tôi cũng sẽ viết kịch bản nhỏ tp, nó sẽ xuất ra các đối số được phân tách bằng ký hiệu ://: và số:
==
#!/bin/bash
tiếng vang -n "@$#"
trong khi [[ $1 != "" ]]; làm echo -n ":$1"; sự thay đổi; xong
tiếng vọng
==

Chế độ bình thường (chọn đối số bằng ký tự khoảng trắng):
x $ thử mèo | xargs ./tp
@8:arg1:arg2:space:arg3 trích dẫn:arg4 đã thoát:arg5:with:continue
Tệp được chia thành các đối số sử dụng ký tự khoảng trắng, nhưng các dòng được trích dẫn và thoát bằng ký tự "\" vẫn còn nguyên.

Chế độ bình thường với việc nhóm theo hàng không khác với chế độ trước ở giai đoạn này.

Tách dòng. Hãy tạo một tệp thử nghiệm thứ hai bằng lệnh sau:
x $ cp test testz && printf "\0arg6" >> testz
Hãy kiểm tra
x $ mèo testz | xargs -0 ./tp
@2:arg1
không gian arg2
"arg3 được trích dẫn"
arg4\ đã thoát
arg5 với
Tiếp tục
:arg6

Như bạn có thể thấy, chỉ có 2 đối số. Đối số đầu tiên dài, giữ nguyên dòng mới, dấu ngoặc kép và \, và đối số thứ hai là arg6. Trong tệp, chúng được phân tách bằng ký tự null.

Về việc phân tách các tham số, có thể nói thêm một điều nữa về tùy chọn -d, tùy chọn này chỉ định một dấu phân cách mới. Ví dụ: hãy thử sử dụng "3" làm dấu phân cách.
x $ thử mèo | xargs -d 3 ./tp
@2:arg1
không gian arg2
"arg: được trích dẫn"
arg4\ đã thoát
arg5 với
Tiếp tục
File đã được chia thành 2 phần tại vị trí có ký hiệu "3". Đáng chú ý, bằng cách này bạn có thể mô phỏng tùy chọn -0
x $ mèo testz | xargs -d "\x00" ./tp
@2:arg1
không gian arg2
"arg3 được trích dẫn"
arg4\ đã thoát
arg5 với
Tiếp tục
:arg6

Có vẻ như chúng ta đã sắp xếp việc phân chia luồng đầu vào thành các đối số, hãy chuyển sang phần thay thế tham số.

Vì vậy, sau các tùy chọn của nó, xarg chờ một lệnh mà nó sẽ thực thi. Tất cả các đối số đến được chia thành các nhóm, sau đó lệnh đã chođược gọi cho mỗi nhóm và tất cả đối số từ nhóm đó sẽ được truyền cho nhóm đó.

Bây giờ hãy xem các nhóm được hình thành như thế nào.

1. Nếu không có tùy chọn thì chỉ có một nhóm, tất cả các đối số từ luồng đầu vào sẽ rơi vào đó. Có thể nói là một nhóm có kích thước vô hạn :)

2. Tùy chọn -L n chỉ định việc nhóm theo dòng. Lệnh được truyền đối số trên n dòng. Tôi sẽ chứng minh bằng các ví dụ.
Nhóm theo 1 dòng:
x $ thử mèo | xargs -L 1 ./tp
@1:arg1
@2:arg2:dấu cách
@1:arg3 được trích dẫn
@1:arg4 đã thoát
@3:arg5:with:tiếp tục
Bạn có thể thấy dòng thứ hai chứa 2 đối số, vì cả hai đều nằm trên cùng một dòng. Và dòng cuối cùng thực sự là 3, vì dòng áp chót được “kéo dài” do khoảng trống ở cuối.

Bây giờ nhóm theo 2 dòng. Lệnh chứa dòng 1 và 2; 3 và 4; và mồ côi thứ 5:
x $ thử mèo | xargs -L 2 ./tp
@3:arg1:arg2:dấu cách
@2:arg3 được trích dẫn:arg4 đã thoát
@3:arg5:with:tiếp tục

3. Nhóm theo đối số, được chỉ định bởi tùy chọn -n x. Ở đây mọi thứ đều minh bạch: các đối số được nhóm thành các phần x và được chuyển tới lệnh.
Đối với một đối số:
x $ thử mèo | xargs -n 1 ./tp
@1:arg1
@1:arg2
@1:khoảng trống
@1:arg3 được trích dẫn
@1:arg4 đã thoát
@1:arg5
@1:với
@1:tiếp tục
Mỗi đối số 2:
x $ thử mèo | xargs -n 2 ./tp
@2:arg1:arg2
@2:space:arg3 được trích dẫn
@2:arg4 đã thoát:arg5
@2:với:tiếp tục

3. Chế độ thay thế - tùy chọn -I. Để bắt đầu, chúng ta phải nhớ lại rằng trong chế độ này Các đối số từ luồng đầu vào được phân tích cú pháp khác nhau. Mỗi dòng là một đối số; các dòng không được nối với nhau. Thứ hai, tùy chọn -I có một tham số - một chuỗi, được thay thế trong lệnh bằng một đối số:
x $ echo -e "A B\nC D" | xargs -I _ ./tp =_+_=
@1:=A B+A B=
@1:=C D+C D=
Dễ dàng nhận thấy ký tự _ được chỉ định làm chuỗi thay thế đối số, được sử dụng 2 lần trong lệnh. Bạn cũng có thể thấy rằng các đối số được phân bổ dưới dạng toàn bộ dòng và khoảng trắng không ảnh hưởng đến việc phân tích cú pháp. Lệnh được gọi cho mỗi đối số.

Đó là tất cả với sự thay thế. Hãy xem xét các tùy chọn quan trọng còn lại
-r - không thực thi lệnh nếu không có đối số:
x $ cat /dev/null | xargs ./tp
@0
x $ cat /dev/null | xargs -r ./tp
x$
Như bạn có thể thấy, trong trường hợp thứ hai lệnh không được thực thi.

P - xargs sẽ yêu cầu xác nhận để thực thi từng lệnh.

Điều này hoàn thành hướng dẫn ngắn. Hóa ra nó không ngắn lắm, nhưng tôi hy vọng nó có thể hiểu được;)