Bạn cần xâu chuỗi một số lệnh Linux lại với nhau, nhưng một trong số chúng không chấp nhận đầu vào theo đường ống? xargs
có thể lấy đầu ra từ một lệnh và gửi đến lệnh khác dưới dạng các tham số.
Tất cả các tiện ích Linux tiêu chuẩn đều có ba luồng dữ liệu được liên kết với chúng. Chúng là dòng đầu vào chuẩn (stdin), dòng đầu ra chuẩn (stdout) và dòng lỗi chuẩn (stderr).
Các luồng này hoạt động với văn bản. Chúng tôi gửi đầu vào (stdin) cho một lệnh bằng cách sử dụng văn bản và phản hồi (stdout) được ghi vào cửa sổ đầu cuối dưới dạng văn bản. Thông báo lỗi cũng được ghi vào cửa sổ đầu cuối dưới dạng văn bản (stderr).
Một trong những tính năng tuyệt vời của các hệ điều hành giống như Linux và Unix là khả năng chuyển đầu ra stdout từ một lệnh thành đầu vào stdin của lệnh thứ hai. Lệnh đầu tiên không quan tâm rằng đầu ra của nó không đến cửa sổ đầu cuối và lệnh thứ hai không quan tâm rằng đầu vào của nó không đến từ bàn phím.
Mặc dù tất cả các lệnh Linux đều có ba luồng tiêu chuẩn, nhưng không phải tất cả chúng đều chấp nhận stdout của lệnh khác làm đầu vào cho stdin của chúng. Điều đó có nghĩa là bạn không thể chuyển đầu vào cho chúng.
xargs
là một lệnh để xây dựng các đường ống thực thi bằng cách sử dụng các luồng dữ liệu tiêu chuẩn. Bằng cách sử dụng xargs
chúng ta có thể thực hiện các lệnh chẳng hạn như echo
, rm
, và mkdir
chấp nhận đầu vào tiêu chuẩn làm đối số.
Lệnh xargs
xargs
sẽ chấp nhận đầu vào theo đường ống. Nó cũng có thể chấp nhận đầu vào từ một tệp. xargs
sử dụng đầu vào đó làm tham số cho các lệnh mà chúng tôi đã yêu cầu nó hoạt động. Nếu chúng tôi không nói xargs
để làm việc với một lệnh cụ thể, nó sẽ mặc định sử dụng echo
.
Chúng tôi có thể sử dụng điều đó để chứng minh cách xargs
sẽ luôn tạo ra một dòng đầu ra, ngay cả từ đầu vào nhiều dòng.
Nếu chúng ta sử dụng -1
(liệt kê một tệp trên mỗi dòng) với tùy chọn ls
, chúng tôi nhận được một cột tên tệp.
ls -1 ./*.sh
Điều này liệt kê các tệp kịch bản shell trong thư mục hiện tại.
Chúng tôi nhận được một cột duy nhất như mong đợi. Nếu chúng ta vượt qua xargs
chúng ta nhận được gì?
ls -1 ./*.sh | xargs
Đầu ra được ghi vào cửa sổ đầu cuối, dưới dạng một dòng văn bản dài.
Đó là khả năng mà chúng ta hãy xargs
nạp các tham số vào các lệnh khác.
Sử dụng xargs Với wc
Chúng ta có thể sử dụng xargs
dễ dàng có wc
đếm các từ, ký tự và dòng trong nhiều tệp.
ls *.page | xargs wc
Đây là những gì sẽ xảy ra:
-
ls
liệt kê các tệp * .page và chuyển danh sách tớixargs
. -
xargs
chuyển tên tệp chowc
. -
wc
xử lý tên tệp như thể nó đã nhận chúng dưới dạng tham số dòng lệnh.
Số liệu thống kê cho mỗi tệp được hiển thị cùng với tổng tổng thể.
Sử dụng xargs có xác nhận
Chúng ta có thể sử dụng -p
(tương tác) tùy chọn để có xargs
nhắc chúng tôi xác nhận rằng chúng tôi rất vui khi nó tiếp tục.
Nếu chúng ta chuyển một chuỗi tên tệp đến touch
, xuyên qua xargs
, touch
sẽ tạo các tệp cho chúng tôi.
echo 'one two three' | xargs -p touch
Lệnh sẽ được thực hiện được hiển thị và xargs
đợi chúng tôi trả lời bằng cách nhập “y” hoặc “Y” hoặc “n” hoặc “N” và nhấn Enter.
Nếu bạn chỉ nhấn Enter, nó được coi là “n”. Lệnh chỉ được thực thi nếu bạn gõ “y” hoặc “Y”.
Chúng tôi nhấn “y” và nhấn Enter. Chúng ta có thể sử dụng ls
để kiểm tra xem các tệp đã được tạo chưa.
ls one two three
Sử dụng xargs với nhiều lệnh
Chúng ta có thể sử dụng nhiều lệnh với xargs
bằng cách sử dụng -I
(đối số ban đầu) tùy chọn.
Tùy chọn này xác định một “chuỗi thay thế”. Bất cứ nơi nào mã thông báo cho chuỗi thay thế xuất hiện trong dòng lệnh, các giá trị được cung cấp cho xargs
được chèn vào.
Hãy sử dụng tree
lệnh để xem các thư mục con từ thư mục hiện tại. Các -d
(thư mục) tùy chọn nguyên nhân tree
để bỏ qua các tệp và chỉ báo cáo trên các thư mục.
tree -d
Có một thư mục con duy nhất được gọi là “hình ảnh”.
Trong một tệp có tên “directories.txt”, chúng tôi có tên của một số thư mục mà chúng tôi muốn tạo. Chúng ta có thể xem nội dung của nó bằng cách sử dụng cat
.
cat directories.txt
Chúng tôi sẽ sử dụng điều này làm dữ liệu đầu vào cho xargs
. Lệnh chúng ta sẽ làm là:
cat directories.txt | xargs -I % sh -c 'echo %; mkdir %'
Điều này bị phá vỡ như thế này:
-
cat directories.txt |: Thao tác này đẩy nội dung của tệp directrories.txt (tất cả các tên thư mục mới) vào
xargs
. - xargs -I%: Điều này xác định một “chuỗi thay thế” với mã thông báo “%”.
-
sh -c: Điều này bắt đầu một vỏ con mới. Các
-c
(lệnh) ra lệnh cho trình bao đọc các lệnh từ dòng lệnh. -
‘echo%; mkdir% ‘: mỗi mã thông báo “%” sẽ được thay thế bằng tên thư mục được chuyển qua
xargs
. Cácecho
lệnh sẽ in tên thư mục; cácmkdir
lệnh sẽ tạo thư mục.
Các thư mục được liệt kê từng cái một.
Chúng ta có thể sử dụng tree
một lần nữa để xác minh các thư mục đã được tạo.
tree -d
Sao chép tệp sang nhiều vị trí
Chúng ta có thể sử dụng xargs
để cho phép chúng tôi sao chép tệp đến nhiều vị trí bằng một lệnh duy nhất.
Chúng tôi sẽ đưa tên của hai thư mục vào xargs
như các tham số đầu vào. Chúng tôi sẽ nói xargs
để chỉ chuyển một trong các tham số này tại một thời điểm cho lệnh mà nó đang làm việc.
Trong trường hợp này, lệnh là cp
. Vì vậy, hiệu quả là để gọi cp
hai lần, mỗi lần với một trong hai thư mục dưới dạng tham số dòng lệnh. Các xargs
tham số cho phép điều này xảy ra là -n
(số tối đa) tùy chọn. Chúng tôi sẽ đặt điều này là một.
Chúng tôi cũng đang sử dụng -v
(dài dòng) tùy chọn với cp
để nó báo cáo những gì đang xảy ra.
echo ~/Backups/ ~/Documents/page-files/ | xargs -n 1 cp -v ./*.page
Các tệp được sao chép vào hai thư mục, một thư mục tại một thời điểm. cp
báo cáo từng hành động sao chép tệp để chúng tôi có thể thấy chúng đang diễn ra.
Xóa tệp trong thư mục lồng nhau
Nếu tên tệp có khoảng trắng và các ký tự lạ trong đó — chẳng hạn như ký tự dòng mới— xargs
sẽ không thể giải thích chúng một cách chính xác. Chúng ta có thể khắc phục vấn đề đó bằng cách sử dụng tùy chọn -0 (null terminator). Điều này nói với xargs
để sử dụng ký tự null làm dấu phân cách cuối cùng cho tên tệp.
Chúng tôi sẽ sử dụng find
trong ví dụ này. find
có tùy chọn riêng để xử lý khoảng trắng và các ký tự lạ trong tên tệp. Nó là -print0
(tên đầy đủ, ký tự rỗng).
find . -name "*.png" -type f -print0 | xargs -0 rm -v -rf "{}"
Điều này bị phá vỡ như thế này:
-
tìm thấy . -tên “* .png”:
find
sẽ tìm kiếm từ thư mục hiện tại “.” cho các đối tượng có tên khớp với “* .png” là tệp (type -f
). - -print0: tên sẽ được kết thúc bởi một ký tự rỗng và khoảng trắng và các ký tự lạ sẽ được cung cấp cho.
- xargs -0: xargs cũng sẽ xem xét các tên tệp được kết thúc bằng null và dấu cách và các ký tự lạ sẽ không gây ra vấn đề.
-
rm -v -rf “{}”: rm sẽ dài dòng và tường thuật những gì đang xảy ra (
-v
). Nó sẽ là đệ quy (-r) và xem qua các thư mục con lồng nhau và sẽ xóa các tệp mà không cần nhắc (-f
). “{}” Được thay thế bằng mỗi tên tệp.
Tất cả các thư mục con được tìm kiếm và các tệp phù hợp với mẫu tìm kiếm sẽ bị xóa.
Xóa các thư mục lồng nhau
Giả sử chúng tôi muốn xóa một tập hợp các thư mục con lồng nhau. tree
sẽ cho chúng tôi thấy chúng.
tree -d
find . -name "level_one" -type d printo | xargs -o rm -v -rf "{}"
Lệnh này sẽ sử dụng find để tìm kiếm đệ quy trong thư mục hiện tại. Mục tiêu tìm kiếm là một thư mục được gọi là “level_one”. Tên thư mục được chuyển qua xargs
đến rm
.
Những thay đổi quan trọng duy nhất giữa lệnh này và lệnh trước đó là, cụm từ tìm kiếm là tên của thư mục trên cùng và -type d
nói với find
để tìm thư mục, không phải tệp.
Tên của mỗi thư mục được in khi nó bị xóa. Chúng tôi có thể kiểm tra với tree
:
tree -d
Tất cả các thư mục con lồng nhau sẽ bị xóa.
Xóa tất cả các tệp, ngoại trừ một loại tệp
Chúng ta có thể sử dụng find
, xargs
và rm
để xóa tất cả các tệp ngoại trừ một loại mà chúng tôi muốn giữ lại. Nó hơi phản trực giác, nhưng chúng tôi cung cấp tên của loại tệp mà chúng tôi muốn giữ, không phải tên của những người mà chúng tôi muốn xóa.
Các -not
tùy chọn nói với find
để trả về tên của các tệp đừng phù hợp với mẫu tìm kiếm. Chúng tôi đang sử dụng -I
(đối số ban đầu) với xargs
một lần nữa. Lần này mã thông báo chuỗi thay thế mà chúng tôi đang xác định là “{}”. Điều này sẽ hoạt động chính xác giống như mã thông báo chuỗi thay thế mà chúng tôi đã tạo trước đó, tình cờ là “%”.
find . -type f -not - name "*.sh" -print0 | xargs -0 -I {} rm -v {}
Chúng tôi có thể kiểm tra với ls
. Các tệp duy nhất còn lại trong thư mục là những tệp phù hợp với mẫu tìm kiếm “* .sh”.
ls -l
Tạo tệp lưu trữ với Xargs
Chúng ta có thể sử dụng find
để tìm kiếm các tệp và chuyển chúng qua xargs
đến tar
, để tạo tệp lưu trữ.
Chúng tôi sẽ tìm kiếm trong thư mục hiện tại. Mẫu tìm kiếm là “* .page” vì vậy chúng tôi sẽ tìm kiếm các tệp “.page”.
find ./ - name "*.page" -type f -print0 | xargs -0 -tar -cvzf page_files.tar.gz
Các tệp được liệt kê như mong đợi, khi tệp lưu trữ được tạo.
Công cụ hòa giải dữ liệu
Đôi khi bạn cần một chút giàn giáo khi xếp chồng mọi thứ lại với nhau. xargs
thu hẹp khoảng cách giữa các lệnh có thể bơm ra thông tin và các lệnh không được xây dựng để tiếp nhận thông tin đó.
Cả hai xargs
và find
có một số lượng lớn các tùy chọn. Bạn được khuyến khích xem các trang người đàn ông của họ để tìm hiểu thêm.