% echo -e '1\n2' | parallel "bash -c 'echo :\$1' '' {}"
:1
:2
% echo -e '1\n2' | parallel bash -c 'echo :\$1' '' {}
%
Ich würde erwarten, dass die zweite Zeile genauso funktioniert.
% echo -e '1\n2' | parallel "bash -c 'echo :\$1' '' {}"
:1
:2
% echo -e '1\n2' | parallel bash -c 'echo :\$1' '' {}
%
Ich würde erwarten, dass die zweite Zeile genauso funktioniert.
Antworten:
parallel
führt den Befehl in einer Schale bereits (die Schale durch bestimmt wird , ist parallel
unter Verwendung von Heuristiken (die Absicht ist , die gleiche Schale wie die aufzurufen parallel
aufgerufen wurde aus ). Sie Das Set kann $PARALLEL_SHELL
variabel die Schale zu fixieren).
Es ist kein Befehl, an den Sie übergeben, parallel
wie Sie es für den Befehl env
oder tun würden xargs
, sondern eine Shell-Befehlszeile (wie Sie es für den eval
Befehl tun würden ).
Wie für eval
, in parallel arg1 arg2
, werden parallel
diese Argumente mit Leerzeichen dazwischen verkettet (so wird es arg1 arg2
) und diese Zeichenfolge wird an übergeben <the-shell> -c
.
Zitieren Sie die Argumente, die an parallel
stdin übergeben werden, parallel
in dem Format, das von dieser bestimmten Shell erwartet wird (eine schwierige und fehleranfällige Aufgabe, weshalb Sie feststellen werden, dass in parallel
Changelog () viele Fehler behoben wurden. Einige sind bis zum 06.03.2017)) noch nicht behoben und hängen sie an diese Befehlszeile an.
So zum Beispiel, wenn von innen aufgerufen bash
,
echo "foo'bar" | parallel echo foo
Hätte parallelen Anruf bash -c
mit echo foo foo\'bar
als Kommandozeile. Und wenn von innen rc
(oder mit PARALLEL_SHELL=rc
) rc -c
mit aufgerufen echo foo foo''''bar
.
In deinem:
parallel bash -c 'echo :\$1' '' {}
parallel
verkettet die folgenden Argumente:
bash -c echo :$1 {}
Und mit dem {}
erweiterten und im richtigen Format zitierten Format für die Shell, von der aus Sie aufrufen parallel
, wird das übergeben, an <that-shell> -c
das bash -c echo
mit :$1
in $0
und das aktuelle Argument in aufgerufen wird $1
.
So parallel
funktioniert das nicht . Hier möchten Sie wahrscheinlich:
printf '1\n2\n' | PARALLEL_SHELL=bash parallel 'echo :{}'
Um zu sehen, was parallel
funktioniert, können Sie es unter strace -fe execve
(oder dem Äquivalent auf Ihrem System, wenn nicht Linux) ausführen .
Hier könnten Sie GNU verwenden, xargs
anstatt parallel
eine einfachere Verarbeitung näher an das zu bringen, was Sie erwarten:
printf '1\n2\n' | xargs -rn1 -P4 bash -c 'echo ":$1"' ''
Siehe auch die Diskussion unter https://lists.gnu.org/archive/html/bug-parallel/2015-05/msg00005.html
Beachten Sie, dass in bash -c 'echo foo' '' foo
, machst du $0
die leere Zeichenfolge für den Inline-Skript. Ich würde das vermeiden, da dies $0
auch in Fehlermeldungen verwendet wird. Vergleichen Sie:
$ bash -c 'echo x > "$1"' '' /
: /: Is a directory
mit.
$ bash -c 'echo x > "$1"' bash /
bash: /: Is a directory
Beachten Sie auch, bash
dass echo
das Nicht- Zitieren von Variablen eine ganz besondere Bedeutung hat und im Allgemeinen nicht für beliebige Daten verwendet werden kann.