Paralelizar una función usando xargs y variables separadas

Paralelizar una función usando xargs y variables separadas

Tengo un archivo de texto de cuatro líneas con 1, 2, 3 y 4 en cada línea. Además, tengo una función que quiero paralelizar:foo() { echo "$1 is not $2"; }

Exporto la función:export -f foo

Ahora quiero llamar a la función con parámetros de los archivos de texto usandoxargs para paralelizar.YTambién quiero usar una variable ( a=0) como parámetro en la función. Entonces llamaría a la función como:cat txt | xargs -I "{}" -P 2 bash -c 'foo {} $a'

PEROesto ignora la variable ( a=0). Y salidas:

"1 no es"... "4 no es", etc.

Si llamo: cat txt | xargs -I "{}" -P 2 bash -c 'foo {} 0'funciona y obtengo el resultado correcto

"1 no es0" ... "4 no es0" etc

Pero necesito llamarlo usando la variable ( a=0) y no usando cero. ¿Cómo puedo hacerlo?

Respuesta1

Incrustar el {}código de shell siempre es una mala idea, ya que introduce una vulnerabilidad de inyección de comandos. Siempre es mejor pasar datos como argumentos separados (sin código).

Además -I, sin -d/ -0todavía se ahoga con comillas y barras invertidas y elimina los espacios en blanco iniciales. Con GNU xargs(que debes usar porque ya estás usando la -Pextensión GNU), lo mejor es usarlo -d '\n'para pasar cada línea de entrada como argumento separado.

xargs -a txt -rd'\n' -P2 -n1 bash -c 'foo "$2" "$1"' bash "$a"

(llama a una bashinvocación para cada 1línea de la entrada con el contenido de $ay la línea actual como argumentos separados a los que se hace referencia como $1y $2en el script de shell en línea).

O con -I:

xargs -a txt -rd'\n' -P2 -I'{}' bash -c 'foo "$1" "$2"' bash {} "$a"

Aquí puede cambiar a zshque tiene una zargsfunción de carga automática que puede realizar procesamiento paralelo al estilo GNU xargs, incluidas funciones sin tener que ejecutar invocaciones de shell separadas o exportar funciones como xargslo hace.

$ autoload zargs
$ foo() print -r - $1 is not $2
$ zargs -P2 -I {} {1..4} -- foo {} $a
1 is not foo
2 is not foo
3 is not foo
4 is not foo

Respuesta2

Con GNU Parallel se ve así:

foo() { echo "$1 is not $2"; }
export -f foo
seq 4 > txt
a=0
cat txt | parallel foo {} $a

información relacionada