Estou tentando usar xargs para chamar uma função mais complexa em 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
Isso retorna o erro
xargs: echo_var: No such file or directory
Quaisquer idéias sobre como eu posso usar o xargs para fazer isso, ou qualquer outra solução, serão bem-vindas.
Respostas:
A exportação da função deve fazê-lo (não testado):
Você pode usar o builtin em
printf
vez do externoseq
:Além disso, usar
return 0
eexit 0
assim mascara qualquer valor de erro que possa ser produzido pelo comando que o precede. Além disso, se não houver erro, é o padrão e, portanto, um pouco redundante.@phobic menciona que o comando Bash poderia ser simplificado para
movendo o
{}
diretamente dentro dele. Mas é vulnerável à injeção de comandos, como apontado por @Sasha.Aqui está um exemplo de por que você não deve usar o formato incorporado:
Outro exemplo de por que não :
É isso que é produzido usando o formato seguro :
Isso é comparável ao uso de consultas SQL parametrizadas para evitar injeção .
Estou usando
date
uma substituição de comando ou entre aspas aqui, em vez dorm
comando usado no comentário de Sasha, pois não é destrutivo.fonte
echo_var
, que é uma função neste script, não um processo (programa) no seu PATH. O que a solução de Dennis faz é exportar a função que os processos filho bash devem usar, bifurcar para o subprocesso e executar lá._
e\
, sem eles, não estava trabalhando para mim_
) fornece um espaço reservado paraargv[0]
($0
) e quase tudo pode ser usado lá. Acho que adicionei a barra invertida-ponto-e-vírgula (\;
) por causa de seu uso para encerrar a-exec
cláusulafind
, mas funciona para mim sem ela aqui. De fato, se a função fosse usada em$@
vez de$1
, ela veria o ponto-e-vírgula como um parâmetro, portanto, ela deve ser omitida.bash -c 'echo_var "{}"'
. Portanto, você não precisa do _ {} no final.O uso do GNU Parallel é assim:
Se você usa a versão 20170822, nem precisa
export -f
, desde que tenha executado isso:fonte
sh: parallel_bash_environment: line 67: unexpected EOF while looking for matching
'' sh: parallel_bash_environment: linha 79: erro de sintaxe: final inesperado do arquivo sh: erro ao importar definição de função 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: linha 79: erro de sintaxe: final inesperado arquivo / usr / local / bin / bash: erro ao importar definição de função para `...Algo assim deve funcionar também:
fonte
Talvez isso seja uma prática ruim, mas você, se estiver definindo funções em um
.bashrc
ou outro script, poderá agrupar o arquivo ou pelo menos as definições de função com uma configuração deallexport
:fonte