To wydaje się być najbezpieczniejszą wersją.
tr '[\n]' '[\0]' < a.txt | xargs -r0 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
( -0
Mogą być usunięte i tr
zastąpione przekierowania (lub plik można zastąpić null oddzielone plik zamiast). Jest to przede wszystkim tam, ponieważ używam głównie xargs
ze find
przy -print0
wyjściu) (To może również być istotna w xargs
wersjach bez -0
rozszerzenia)
Jest to bezpieczne, ponieważ podczas wykonywania argumenty przekazują parametry do powłoki jako tablicę. Powłoka (przynajmniej bash
) przekazałaby je następnie jako niezmienioną tablicę do innych procesów, gdy wszystkie zostaną uzyskane przy użyciu["$@"][1]
Jeśli użyjesz ...| xargs -r0 -I{} bash -c 'f="{}"; command "$f";' ''
, przypisanie nie powiedzie się, jeśli ciąg zawiera podwójne cudzysłowy. Dotyczy to każdego wariantu używającego -i
lub -I
. (Ponieważ jest zamieniany na ciąg znaków, zawsze możesz wstrzykiwać polecenia, wstawiając nieoczekiwane znaki (takie jak cudzysłowy, znaki wsteczne lub znaki dolara) do danych wejściowych)
Jeśli polecenia mogą przyjmować tylko jeden parametr na raz:
tr '[\n]' '[\0]' < a.txt | xargs -r0 -n1 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
Lub z nieco mniejszą ilością procesów:
tr '[\n]' '[\0]' < a.txt | xargs -r0 /bin/bash -c 'for f in "$@"; do command1 "$f"; command2 "$f"; done;' ''
Jeśli masz GNU xargs
lub inny z -P
rozszerzeniem i chcesz uruchomić 32 procesy równolegle, każdy z nie więcej niż 10 parametrami dla każdego polecenia:
tr '[\n]' '[\0]' < a.txt | xargs -r0 -n10 -P32 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
Powinno to być odporne na wszelkie znaki specjalne na wejściu. (Jeśli dane wejściowe są rozdzielone zerą.) tr
Wersja otrzyma nieprawidłowe dane wejściowe, jeśli niektóre wiersze zawierają znaki nowego wiersza, ale jest to nieuniknione w przypadku pliku oddzielonego znakiem nowego wiersza.
Pusty pierwszy parametr dla bash -c
wynika z tego: (Ze strony podręcznika bash
man ) (Dzięki @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.