Це здається найбезпечнішою версією.
tr '[\n]' '[\0]' < a.txt | xargs -r0 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
( -0
Можуть бути видалені і tr
замінені редиректу (або файл може бути замінений нулем відокремлений файл , а). В основному там , так як я в основному використовують xargs
з find
з -print0
виходом) (Це може також мати значення в xargs
версіях без -0
розширення)
Це безпечно, оскільки аргументи передають параметри оболонці як масиву під час її виконання. Оболонка (принаймні bash
) передавала б їх як незмінний масив іншим процесам, коли всі отримані за допомогою["$@"][1]
Якщо ви використовуєте ...| xargs -r0 -I{} bash -c 'f="{}"; command "$f";' ''
, призначення не вдасться, якщо рядок містить подвійні лапки. Це справедливо для кожного варіанту, що використовує -i
або -I
. (Завдяки тому, що він замінюється на рядок, ви завжди можете вводити команди, вставляючи у вхідні дані несподівані символи (наприклад, лапки, задні символи чи знаки долара))
Якщо команди можуть приймати лише один параметр одночасно:
tr '[\n]' '[\0]' < a.txt | xargs -r0 -n1 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
Або з дещо меншими процесами:
tr '[\n]' '[\0]' < a.txt | xargs -r0 /bin/bash -c 'for f in "$@"; do command1 "$f"; command2 "$f"; done;' ''
Якщо у вас є GNU xargs
або інше з -P
розширенням, і ви хочете запустити 32 процеси паралельно, кожен з не більше 10 параметрів для кожної команди:
tr '[\n]' '[\0]' < a.txt | xargs -r0 -n10 -P32 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
Це має бути надійним щодо будь-яких спеціальних символів у вводі. (Якщо вхід розділено з нуля.) tr
Версія отримає недійсний ввід, якщо деякі рядки містять нові рядки, але це неминуче, якщо файл, розділений за допомогою нового рядка.
Порожній перший параметр для bash -c
пояснюється цим: (зі bash
сторінки man ) (спасибі @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.