% 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:
parallelexecuta o comando em um shell já (que desembolsar é é determinada pelo parallelusando heurística (a intenção de ser para invocar o mesmo shell como o parallelfoi invocada a partir ). Você pode definir a $PARALLEL_SHELLvariável para corrigir o shell).
Não é um comando que você está passando parallelcomo faria para o comando envou xargs, mas uma linha de comando do shell (como você faria para o evalcomando).
Como por eval, em parallel arg1 arg2, parallelestá 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 parallelstdin do, parallelcite-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 parallelChangelog ( 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 -ccom echo foo foo\'barcomo a linha de comando. E se chamado de dentro rc(ou com PARALLEL_SHELL=rc) rc -ccom 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> -cque será chamado bash -c echocom :$1in $0e o argumento atual in $1.
Não é assim que parallelfunciona. Aqui, você provavelmente desejaria:
printf '1\n2\n' | PARALLEL_SHELL=bash parallel 'echo :{}'
Para ver o que parallelfaz, 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 xargsvez de parallelobter 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 $0a string vazia para esse script embutido. Eu evitaria isso, pois isso $0també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 bashe echogeralmente não pode ser usado para dados arbitrários.