2012-06-12 15 views
92

Estoy tratando de usar xargs para llamar a una función más compleja en paralelo.Llamar funciones de shell con xargs

#!/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 

¿Alguna idea sobre cómo puedo usar xargs para lograr esto, o cualquier otra solución (s) sería bienvenido.

+1

Peligro, user1148366, Peligro! No use bash para la programación paralela, se encontrará con tantos problemas. Use C/C++ y pthreads, o subprocesos de Java, o cualquier cosa que lo haga reflexionar detenidamente sobre lo que está haciendo, porque la programación paralela requiere una gran cantidad de reflexión para hacerlo bien. –

+17

@DavidSouther Si las tareas son independientes, como convertir todos estos archivos de imagen a png, entonces no se preocupe. Es cuando tienes la sincronización (más allá de esperar a que todos terminen) y la comunicación se vuelve desordenada. –

Respuesta

87

Exportación de la función debería hacerlo (no probado):

export -f echo_var 
seq -f "n%04g" 1 100 | xargs -n 1 -P 10 -I {} bash -c 'echo_var "[email protected]"' _ {} 

Usted puede usar la orden interna printf en lugar de la seq externa:

printf "n%04g\n" {1..100} | xargs -n 1 -P 10 -I {} bash -c 'echo_var "[email protected]"' _ {} 

Además, el uso return 0 y exit 0 como que enmascara cualquier valor de error que puede ser producido por el comando que lo precede. Además, si no hay ningún error, es el predeterminado y por lo tanto algo redundante.

+7

Un poco más de discusión: xargs ejecuta una instancia completamente nueva del proceso nombrado. En este caso, proporcione el nombre '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 los procesos bash de los niños se usen, luego se bifurca al subproceso y se ejecuta allí. –

+4

cuál es el significado de '_' y' '\' ', sin ellos no funcionaba para mí – Hashbrown

+6

@Hashbrown: El guión bajo (' _') proporciona un marcador de posición para 'argv [0]' ('$ 0 ') y casi cualquier cosa podría usarse allí. Creo que agregué la barra invertida-punto y coma ('\;') debido a su uso en la terminación de la cláusula '-exec' en' find', pero funciona sin mi aquí. De hecho, si la función fuera usar '$ @' en lugar de '$ 1', vería el punto y coma como parámetro, por lo que debería omitirse. –

12

paralelo usando GNU es el siguiente aspecto:

#!/bin/bash 
echo_var(){ 
    echo $1 
    return 0 
} 
export -f echo_var 
seq -f "n%04g" 1 100 | parallel -P 10 echo_var {} 
exit 0 

Si utiliza la versión 20170822 no tienen ni siquiera para export -f siempre y cuando se haya ejecutado la siguiente:

. `which env_parallel.bash` 
seq -f "n%04g" 1 100 | env_parallel -P 10 echo_var {} 
+0

¿dónde consigo shopt para osx? – Nick

+0

NVM se setopt en zsh – Nick

+0

Conseguir este continuación eerror Ole 'sh: parallel_bash_environment: línea 67: EOF inesperado en la búsqueda de juego ' '' sh: parallel_bash_environment: Línea 79: error de sintaxis: fin de archivo inesperado sh: error definición de la función de importación para 'parallel_bash_environment ' /usr/local/bin/bash: parallel_bash_environment: línea 67: EOF inesperado al buscar la coincidencia'' ' /usr/local/bin/bash: parallel_bash_environment: línea 79: error de sintaxis: inesperado Fin del archivo /usr/local/bin/bash: error al importar la definición de función para '... – Nick

5

Algo como esto debe trabaje también:

function testing() { sleep $1 ; } 
echo {1..10} | xargs -n 1 | xargs [email protected] -P4 bash -c "$(declare -f testing) ; testing @ ; echo @ " 
0

Quizás esto sea una mala práctica, pero usted si usted es defin ing funciones en un script .bashrc u otro, se puede envolver el archivo o al menos las definiciones de funciones con un ajuste de allexport:

set -o allexport 

function funcy_town { 
    echo 'this is a function' 
} 
function func_rock { 
    echo 'this is a function, but different' 
} 
function cyber_func { 
    echo 'this function does important things' 
} 
function the_man_from_funcle { 
    echo 'not gonna lie' 
} 
function funcle_wiggly { 
    echo 'at this point I\'m doing it for the funny names' 
} 
function extreme_function { 
    echo 'goodbye' 
} 

set +o allexport 
Cuestiones relacionadas