% echo -e '1\n2' | parallel "bash -c 'echo :\$1' '' {}"
:1
:2
% echo -e '1\n2' | parallel bash -c 'echo :\$1' '' {}
%
Eu esperaria que a segunda linha aja da mesma maneira.
% echo -e '1\n2' | parallel "bash -c 'echo :\$1' '' {}"
:1
:2
% echo -e '1\n2' | parallel bash -c 'echo :\$1' '' {}
%
Eu esperaria que a segunda linha aja da mesma maneira.
Respostas:
parallel
executa o comando em um shell já (que desembolsar é é determinada pelo parallel
usando heurística (a intenção de ser para invocar o mesmo shell como o parallel
foi invocada a partir ). Você pode definir a $PARALLEL_SHELL
variável para corrigir o shell).
Não é um comando que você está passando parallel
como faria para o comando env
ou xargs
, mas uma linha de comando do shell (como você faria para o eval
comando).
Como por eval
, em parallel arg1 arg2
, parallel
está concatenando esses argumentos com espaços no meio (assim torna-se arg1 arg2
) e essa sequência é passada para <the-shell> -c
.
Para os argumentos passados no parallel
stdin do, parallel
cite-os no formato esperado por esse shell em particular (uma tarefa difícil e propensa a erros, e é por isso que você encontrará muitos bugs corrigidos em torno disso no parallel
Changelog ( alguns ainda não foram corrigidos em 06/03/2017)) e o anexam a essa linha de comando.
Por exemplo, se chamado de dentro bash
,
echo "foo'bar" | parallel echo foo
Teria chamada paralela bash -c
com echo foo foo\'bar
como a linha de comando. E se chamado de dentro rc
(ou com PARALLEL_SHELL=rc
) rc -c
com echo foo foo''''bar
.
Na tua:
parallel bash -c 'echo :\$1' '' {}
parallel
concatena os argumentos que dão:
bash -c echo :$1 {}
E com o {}
expandido e citado no formato certo para o shell do qual você está ligando parallel
, passa o <that-shell> -c
que será chamado bash -c echo
com :$1
in $0
e o argumento atual in $1
.
Não é assim que parallel
funciona. Aqui, você provavelmente desejaria:
printf '1\n2\n' | PARALLEL_SHELL=bash parallel 'echo :{}'
Para ver o que parallel
faz, você pode executá-lo em strace -fe execve
(ou equivalente no seu sistema, se não no Linux).
Aqui, você pode usar o GNU em xargs
vez de parallel
obter um processamento mais simples mais próximo do que você está esperando:
printf '1\n2\n' | xargs -rn1 -P4 bash -c 'echo ":$1"' ''
Veja também a discussão em https://lists.gnu.org/archive/html/bug-parallel/2015-05/msg00005.html
Observe que bash -c 'echo foo' '' foo
, você está criando $0
a string vazia para esse script embutido. Eu evitaria isso, pois isso $0
também é usado em mensagens de erro. Comparar:
$ bash -c 'echo x > "$1"' '' /
: /: Is a directory
com.
$ bash -c 'echo x > "$1"' bash /
bash: /: Is a directory
Observe também que deixar variáveis sem aspas tem um significado muito especial bash
e echo
geralmente não pode ser usado para dados arbitrários.