Cela semble être la version la plus sûre.
tr '[\n]' '[\0]' < a.txt | xargs -r0 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
( -0
peut être supprimé et tr
remplacé par une redirection (ou le fichier peut être remplacé par un fichier séparé par null à la place). Il est principalement là car j'utilise principalement xargs
avec find
avec -print0
sortie) (Cela peut également être pertinent sur les xargs
versions sans l' -0
extension)
C'est sûr, car args transmettra les paramètres au shell sous forme de tableau lors de son exécution. Le shell (au moins bash
) les transmettrait ensuite sous la forme d'un tableau non modifié aux autres processus lorsque tous sont obtenus à l'aide de["$@"][1]
Si vous utilisez ...| xargs -r0 -I{} bash -c 'f="{}"; command "$f";' ''
, l'affectation échouera si la chaîne contient des guillemets doubles. Cela est vrai pour chaque variante utilisant -i
ou -I
. (En raison de son remplacement dans une chaîne, vous pouvez toujours injecter des commandes en insérant des caractères inattendus (comme des guillemets, des guillemets ou des signes dollar) dans les données d'entrée)
Si les commandes ne peuvent prendre qu'un paramètre à la fois:
tr '[\n]' '[\0]' < a.txt | xargs -r0 -n1 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
Ou avec un peu moins de processus:
tr '[\n]' '[\0]' < a.txt | xargs -r0 /bin/bash -c 'for f in "$@"; do command1 "$f"; command2 "$f"; done;' ''
Si vous avez GNU xargs
ou un autre avec l' -P
extension et que vous souhaitez exécuter 32 processus en parallèle, chacun avec pas plus de 10 paramètres pour chaque commande:
tr '[\n]' '[\0]' < a.txt | xargs -r0 -n10 -P32 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
Cela devrait être robuste contre tous les caractères spéciaux dans l'entrée. (Si l'entrée est séparée par des valeurs nulles.) La tr
version obtiendra une entrée non valide si certaines des lignes contiennent des retours à la ligne, mais cela est inévitable avec un fichier séparé par des retours à la ligne.
Le premier paramètre vide pour bash -c
est dû à ceci: (À partir de la bash
page de manuel ) (Merci @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.