% echo -e '1\n2' | parallel "bash -c 'echo :\$1' '' {}"
:1
:2
% echo -e '1\n2' | parallel bash -c 'echo :\$1' '' {}
%
Mi aspetto che la seconda riga si comporti allo stesso modo.
% echo -e '1\n2' | parallel "bash -c 'echo :\$1' '' {}"
:1
:2
% echo -e '1\n2' | parallel bash -c 'echo :\$1' '' {}
%
Mi aspetto che la seconda riga si comporti allo stesso modo.
Risposte:
parallel
esegue il comando in una shell già (che shell è è determinato parallel
utilizzando euristiche (l'intenzione è quello di richiamare la stessa shell come quello parallel
è stato invocato da ). È possibile impostare la $PARALLEL_SHELL
variabile per fissare la shell).
Non è un comando a cui stai passando parallel
come faresti per il comando env
o xargs
, ma una riga di comando della shell (come faresti per il eval
comando).
Like for eval
, in parallel arg1 arg2
, parallel
sta concatenando quegli argomenti con spazi in mezzo (così diventa arg1 arg2
) e quella stringa viene passata a <the-shell> -c
.
Per gli argomenti che vengono passati allo parallel
stdin, parallel
citali nel formato previsto da quella particolare shell (un'attività difficile e soggetta a errori, motivo per cui troverai che ci sono stati molti bug corretti attorno a quello nel parallel
Changelog ( alcuni non sono ancora stati corretti a partire dal 06-03-2017)) e lo aggiunge a quella riga di comando.
Ad esempio, se chiamato dall'interno bash
,
echo "foo'bar" | parallel echo foo
Avrebbe chiamata parallela bash -c
con echo foo foo\'bar
come riga di comando. E se chiamato dall'interno rc
(o con PARALLEL_SHELL=rc
) rc -c
con echo foo foo''''bar
.
Nella tua:
parallel bash -c 'echo :\$1' '' {}
parallel
concatena quegli argomenti che danno:
bash -c echo :$1 {}
E con l' {}
espansione e la citazione nel formato giusto per la shell da cui stai chiamando parallel
, passa quello a <that-shell> -c
cui chiamerà bash -c echo
con :$1
in $0
e l'argomento corrente in $1
.
Non è come parallel
funziona. Qui, probabilmente vorresti:
printf '1\n2\n' | PARALLEL_SHELL=bash parallel 'echo :{}'
Per vedere cosa parallel
succede, puoi eseguirlo sotto strace -fe execve
(o l'equivalente sul tuo sistema se non Linux).
Qui, puoi usare GNU xargs
invece di parallel
ottenere un'elaborazione più semplice più vicina a ciò che ti aspetti:
printf '1\n2\n' | xargs -rn1 -P4 bash -c 'echo ":$1"' ''
Vedi anche la discussione su https://lists.gnu.org/archive/html/bug-parallel/2015-05/msg00005.html
Nota che in bash -c 'echo foo' '' foo
, stai creando $0
la stringa vuota per quello script in linea. Lo eviterei poiché $0
viene utilizzato anche nei messaggi di errore. Confrontare:
$ bash -c 'echo x > "$1"' '' /
: /: Is a directory
con.
$ bash -c 'echo x > "$1"' bash /
bash: /: Is a directory
Si noti inoltre che lasciare variabili non quotate ha un significato molto speciale bash
e che echo
generalmente non può essere utilizzato per dati arbitrari.