
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
/ -0
todaví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 -P
extensió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 bash
invocación para cada 1
línea de la entrada con el contenido de $a
y la línea actual como argumentos separados a los que se hace referencia como $1
y $2
en 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 zsh
que tiene una zargs
funció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 xargs
lo 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