J'essaie d'utiliser xargs pour appeler une fonction plus complexe en parallèle.
#!/bin/bash
echo_var(){
echo $1
return 0
}
seq -f "n%04g" 1 100 |xargs -n 1 -P 10 -i echo_var {}
exit 0
Cela renvoie l'erreur
xargs: echo_var: No such file or directory
Toute idée sur la façon dont je peux utiliser xargs pour accomplir cela, ou toute autre solution serait la bienvenue.
Réponses:
L'exportation de la fonction devrait le faire (non testé):
Vous pouvez utiliser le builtin
printf
au lieu de l'externeseq
:De plus, utiliser
return 0
etexit 0
comme ça masque toute valeur d'erreur qui pourrait être produite par la commande la précédant. De plus, s'il n'y a pas d'erreur, c'est la valeur par défaut et donc quelque peu redondante.@phobic mentionne que la commande Bash pourrait être simplifiée à
déplacer le
{}
directement à l'intérieur. Mais il est vulnérable à l'injection de commandes comme le souligne @Sasha.Voici un exemple des raisons pour lesquelles vous ne devriez pas utiliser le format intégré:
Un autre exemple de pourquoi pas :
Voici ce qui est produit en utilisant le format sécurisé :
Ceci est comparable à l'utilisation de requêtes SQL paramétrées pour éviter l' injection .
J'utilise
date
dans une substitution de commande ou entre guillemets échappés ici au lieu de larm
commande utilisée dans le commentaire de Sasha car elle est non destructive.la source
echo_var
, qui est une fonction dans ce script, et non un processus (programme) dans votre PATH. La solution de Dennis est d'exporter la fonction pour les processus bash enfants à utiliser, puis de passer au sous-processus et de s'y exécuter._
et\
, sans eux, cela ne fonctionnait pas pour moi_
) fournit un espace réservé pourargv[0]
($0
) et presque tout peut y être utilisé. Je pense que j'ai ajouté la barre oblique inverse-point-virgule (\;
) en raison de son utilisation pour terminer la-exec
clause dansfind
, mais cela fonctionne pour moi sans elle ici. En fait, si la fonction devait être utilisée à la$@
place de$1
alors, elle verrait le point-virgule comme un paramètre, il devrait donc être omis.bash -c 'echo_var "{}"'
. Vous n'avez donc pas besoin du _ {} à la fin.L'utilisation de GNU Parallel ressemble à ceci:
Si vous utilisez la version 20170822, vous n'avez même pas besoin de le faire
export -f
tant que vous avez exécuté ceci:la source
sh: parallel_bash_environment: line 67: unexpected EOF while looking for matching
'' sh: parallel_bash_environment: ligne 79: erreur de syntaxe: fin inattendue du fichier sh: erreur lors de l'importation de la définition de fonction pourparallel_bash_environment' /usr/local/bin/bash: parallel_bash_environment: line 67: unexpected EOF while looking for matching
'' / usr / local / bin / bash: parallel_bash_environment: ligne 79: erreur de syntaxe: fin inattendue de file / usr / local / bin / bash: erreur lors de l'importation de la définition de la fonction pour `...Quelque chose comme ça devrait fonctionner aussi:
la source
C'est peut-être une mauvaise pratique, mais si vous définissez des fonctions dans un
.bashrc
script ou un autre, vous pouvez envelopper le fichier ou au moins les définitions de fonction avec un paramètre deallexport
:la source