Questa sembra essere la versione più sicura.
tr '[\n]' '[\0]' < a.txt | xargs -r0 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
( -0
Può essere rimosso ed il tr
sostituito con un reindirizzamento (o il file può essere sostituito con un file separato da nullo invece). E 'soprattutto lì dato che uso principalmente xargs
con find
con -print0
uscita) (potrebbe anche essere rilevante sulla xargs
versioni senza la-0
estensione)
È sicuro, poiché args passerà i parametri alla shell come array durante l'esecuzione. La shell (almeno bash
) li passerebbe quindi come array inalterato agli altri processi quando tutti saranno ottenuti usando["$@"][1]
Se lo usi ...| xargs -r0 -I{} bash -c 'f="{}"; command "$f";' ''
, l'assegnazione fallirà se la stringa contiene virgolette doppie. Questo vale per ogni variante che utilizza -i
o -I
. (A causa della sua sostituzione in una stringa, è sempre possibile inserire comandi inserendo caratteri imprevisti (come virgolette, backtick o segni di dollaro) nei dati di input)
Se i comandi possono accettare solo un parametro alla volta:
tr '[\n]' '[\0]' < a.txt | xargs -r0 -n1 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
O con un po 'meno processi:
tr '[\n]' '[\0]' < a.txt | xargs -r0 /bin/bash -c 'for f in "$@"; do command1 "$f"; command2 "$f"; done;' ''
Se hai GNU xargs
o un altro con l' -P
estensione e vuoi eseguire 32 processi in parallelo, ognuno con non più di 10 parametri per ciascun comando:
tr '[\n]' '[\0]' < a.txt | xargs -r0 -n10 -P32 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
Questo dovrebbe essere solido contro qualsiasi carattere speciale nell'input. (Se l'input è nullo separato.) La tr
versione otterrà un input non valido se alcune linee contengono newline, ma ciò è inevitabile con un file separato da newline.
Il primo parametro vuoto per bash -c
è dovuto a questo: (Dalla bash
pagina man ) (Grazie @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.