% echo -e '1\n2' | parallel "bash -c 'echo :\$1' '' {}"
:1
:2
% echo -e '1\n2' | parallel bash -c 'echo :\$1' '' {}
%
Esperaría que la segunda línea actúe igual.
% echo -e '1\n2' | parallel "bash -c 'echo :\$1' '' {}"
:1
:2
% echo -e '1\n2' | parallel bash -c 'echo :\$1' '' {}
%
Esperaría que la segunda línea actúe igual.
Respuestas:
parallel
Ejecuta el comando en una cáscara ya (que la cáscara es está determinado por parallel
el uso de la heurística (con la intención de invocar el mismo shell como el que parallel
se invocó de ). Puede establecer la $PARALLEL_SHELL
variable para fijar la cáscara).
No es un comando al que está pasando parallel
como lo haría para el comando env
o xargs
, sino una línea de comando de shell (como lo haría para el eval
comando).
Al igual que for eval
, in parallel arg1 arg2
, parallel
concatena esos argumentos con espacios intermedios (por lo que se convierte arg1 arg2
) y esa cadena se pasa a <the-shell> -c
.
Para los argumentos que se transmiten en parallel
la entrada estándar, parallel
cítelos en el formato esperado por ese shell en particular (una tarea difícil y propensa a errores, por eso encontrará que se han solucionado muchos errores en parallel
el Registro de cambios ( algunos todavía no se corrigieron a partir del 2017-03-06)) y lo agrega a esa línea de comando.
Entonces, por ejemplo, si se llama desde adentro bash
,
echo "foo'bar" | parallel echo foo
Tendría llamada en paralelo bash -c
con el echo foo foo\'bar
que la línea de comandos. Y si se llama desde dentro rc
(o con PARALLEL_SHELL=rc
) rc -c
con echo foo foo''''bar
.
En tus:
parallel bash -c 'echo :\$1' '' {}
parallel
concatena esos argumentos que da:
bash -c echo :$1 {}
Y con el {}
expandido y citado en el formato correcto para el shell desde el que está llamando parallel
, pasa aquello a <that-shell> -c
lo que llamará bash -c echo
con :$1
in $0
y el argumento actual en $1
.
No es así como parallel
funciona. Aquí, probablemente quieras:
printf '1\n2\n' | PARALLEL_SHELL=bash parallel 'echo :{}'
Para ver qué parallel
hace, puede ejecutarlo strace -fe execve
(o el equivalente en su sistema si no es Linux).
Aquí, puede usar GNU en xargs
lugar de parallel
obtener un procesamiento más simple más cercano a lo que espera:
printf '1\n2\n' | xargs -rn1 -P4 bash -c 'echo ":$1"' ''
Consulte también la discusión en https://lists.gnu.org/archive/html/bug-parallel/2015-05/msg00005.html
Tenga en cuenta que en bash -c 'echo foo' '' foo
, está haciendo $0
la cadena vacía para ese script en línea. Evitaría eso, ya que $0
también se usa en mensajes de error. Comparar:
$ bash -c 'echo x > "$1"' '' /
: /: Is a directory
con.
$ bash -c 'echo x > "$1"' bash /
bash: /: Is a directory
También tenga en cuenta que dejar variables sin comillas tiene un significado muy especial bash
y que echo
generalmente no se puede usar para datos arbitrarios.