Paralelize uma função usando xargs e variáveis ​​separadas

Paralelize uma função usando xargs e variáveis ​​separadas

Eu tenho um arquivo de texto de quatro linhas com 1, 2, 3 e 4 em cada linha. Além disso, tenho uma função que desejo paralelizar:foo() { echo "$1 is not $2"; }

Eu exporto a função:export -f foo

Agora quero chamar a função com parâmetros dos arquivos de texto usados xargs​​para paralelizar.ETambém quero usar uma variável ( a=0) como parâmetro na função. Então, eu chamaria a função como:cat txt | xargs -I "{}" -P 2 bash -c 'foo {} $a'

MASisso ignora a variável ( a=0). E saídas:

"1 não é" ... "4 não é" etc.

Se eu ligar: cat txt | xargs -I "{}" -P 2 bash -c 'foo {} 0'funciona e obtenho a saída correta

"1 não é0" ... "4 não é0" etc.

Mas preciso chamá-lo usando a variável ( a=0) e não usando zero. Como eu posso fazer isso?

Responder1

Incorporar o {}código shell é sempre uma má ideia, pois introduz uma vulnerabilidade de injeção de comando. É sempre melhor passar dados como argumentos separados (sem código).

Além disso -I, sem -d/ -0ainda engasga com aspas, barras invertidas e faixas em branco. Com o GNU xargs(que você deve usar porque já está usando a -Pextensão GNU), o melhor é usar -d '\n'para passar cada linha de entrada como argumento separado

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

(chama uma bashinvocação para cada 1linha da entrada com o conteúdo $ae a linha atual como argumentos separados que são referidos como $1e $2no script shell embutido).

Ou com -I:

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

Aqui você pode mudar para zshqual possui uma zargsfunção autocarregável que pode fazer processamento paralelo à la GNU xargs, inclusive de funções sem ter que executar invocações de shell separadas ou exportar funções como xargsfaz.

$ 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

Responder2

Com o GNU Parallel fica assim:

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

informação relacionada