Estoy tratando de usar xargs para llamar a una función más compleja en paralelo.
#!/bin/bash
echo_var(){
echo $1
return 0
}
seq -f "n%04g" 1 100 |xargs -n 1 -P 10 -i echo_var {}
exit 0
Esto devuelve el error
xargs: echo_var: No such file or directory
Cualquier idea sobre cómo puedo usar xargs para lograr esto, o cualquier otra solución (s) sería bienvenida.
Respuestas:
La exportación de la función debería hacerlo (sin probar):
Puede usar el incorporado en
printf
lugar del externoseq
:Además, el uso
return 0
yexit 0
similares oculta cualquier valor de error que pueda generar el comando que lo precede. Además, si no hay error, es el valor predeterminado y, por lo tanto, algo redundante.@phobic menciona que el comando Bash podría simplificarse para
moviendo el
{}
directamente dentro de él. Pero es vulnerable a la inyección de comandos como lo señaló @Sasha.Aquí hay un ejemplo de por qué no debe usar el formato incrustado:
Otro ejemplo de por qué no :
Esto es lo que se genera con el formato seguro :
Esto es comparable al uso de consultas SQL parametrizadas para evitar la inyección .
Estoy usando
date
una sustitución de comando o entre comillas escapadas aquí en lugar delrm
comando utilizado en el comentario de Sasha, ya que no es destructivo.fuente
echo_var
, que es una función en este script, no un proceso (programa) en su RUTA. Lo que hace la solución de Dennis es exportar la función para que la usen los procesos de bash secundarios, luego se bifurca al subproceso y se ejecuta allí._
y\
, sin ellos, no funcionaba para mí_
) proporciona un marcador de posición paraargv[0]
($0
) y casi cualquier cosa podría usarse allí. Creo que agregué la barra invertida-punto y coma (\;
) debido a su uso para terminar la-exec
cláusulafind
, pero funciona para mí sin ella aquí. De hecho, si la función se usara en$@
lugar de$1
entonces, vería el punto y coma como un parámetro, por lo que debería omitirse.bash -c 'echo_var "{}"'
. Por lo tanto, no necesita el _ {} al final.El uso de GNU Parallel se ve así:
Si usa la versión 20170822, ni siquiera tiene que hacerlo
export -f
siempre que haya ejecutado esto:fuente
sh: parallel_bash_environment: line 67: unexpected EOF while looking for matching
'' sh: paralela_bash_environment: línea 79: error de sintaxis: final inesperado del archivo sh: error al importar la definición de la función paraparallel_bash_environment' /usr/local/bin/bash: parallel_bash_environment: line 67: unexpected EOF while looking for matching
'' / usr / local / bin / bash: parallel_bash_environment: línea 79: error de sintaxis: final inesperado de file / usr / local / bin / bash: error al importar la definición de la función para `...Algo como esto debería funcionar también:
fuente
Tal vez esta sea una mala práctica, pero si está definiendo funciones en una
.bashrc
u otra secuencia de comandos, puede ajustar el archivo o al menos las definiciones de función con una configuración deallexport
:fuente