Đây dường như là phiên bản an toàn nhất.
tr '[\n]' '[\0]' < a.txt | xargs -r0 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
( -0
Có thể được gỡ bỏ và tr
thay thế bằng một chuyển hướng (hoặc tập tin có thể được thay thế bằng một null tách tập tin thay vì). Nó là chủ yếu trong đó kể từ khi tôi chủ yếu sử dụng xargs
với find
với -print0
đầu ra) (Điều này cũng có thể là có liên quan về xargs
các phiên bản mà không có -0
phần mở rộng)
Nó là an toàn, vì args sẽ truyền các tham số cho shell dưới dạng một mảng khi thực hiện nó. Shell (ít nhất bash
) sau đó sẽ chuyển chúng thành một mảng không thay đổi cho các quy trình khác khi tất cả thu được bằng cách sử dụng["$@"][1]
Nếu bạn sử dụng ...| xargs -r0 -I{} bash -c 'f="{}"; command "$f";' ''
, việc gán sẽ thất bại nếu chuỗi chứa dấu ngoặc kép. Điều này đúng cho mọi biến thể sử dụng -i
hoặc -I
. (Do được thay thế thành một chuỗi, bạn luôn có thể chèn các lệnh bằng cách chèn các ký tự không mong muốn (như dấu ngoặc kép, dấu hiệu ngược hoặc ký hiệu đô la) vào dữ liệu đầu vào)
Nếu các lệnh chỉ có thể nhận một tham số tại một thời điểm:
tr '[\n]' '[\0]' < a.txt | xargs -r0 -n1 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
Hoặc với một số quy trình ít hơn:
tr '[\n]' '[\0]' < a.txt | xargs -r0 /bin/bash -c 'for f in "$@"; do command1 "$f"; command2 "$f"; done;' ''
Nếu bạn có GNU xargs
hoặc cái khác có -P
phần mở rộng và bạn muốn chạy song song 32 tiến trình, mỗi tiến trình có không quá 10 tham số cho mỗi lệnh:
tr '[\n]' '[\0]' < a.txt | xargs -r0 -n10 -P32 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
Điều này nên mạnh mẽ chống lại bất kỳ ký tự đặc biệt trong đầu vào. (Nếu đầu vào là null tách biệt.) tr
Phiên bản sẽ nhận được một số đầu vào không hợp lệ nếu một số dòng chứa dòng mới, nhưng điều đó là không thể tránh khỏi với một tệp được phân tách dòng mới.
Tham số đầu tiên trống bash -c
là do điều này: (Từ bash
trang man ) (Cảm ơn @clacke)
-c If the -c option is present, then commands are read from the first non-option argument com‐
mand_string. If there are arguments after the command_string, the first argument is assigned to $0
and any remaining arguments are assigned to the positional parameters. The assignment to $0 sets
the name of the shell, which is used in warning and error messages.