% echo -e '1\n2' | parallel "bash -c 'echo :\$1' '' {}"
:1
:2
% echo -e '1\n2' | parallel bash -c 'echo :\$1' '' {}
%
Spodziewałbym się, że druga linia zachowa się tak samo.
źródło
% echo -e '1\n2' | parallel "bash -c 'echo :\$1' '' {}"
:1
:2
% echo -e '1\n2' | parallel bash -c 'echo :\$1' '' {}
%
Spodziewałbym się, że druga linia zachowa się tak samo.
parallel
uruchamia polecenie w powłoce już (co shell to określa się parallel
za pomocą heurystyki (będący zamiar powołać taką samą powłokę jako jedna parallel
została wywołana z ). Można ustawić $PARALLEL_SHELL
zmienną naprawić powłokę).
To nie jest polecenie, które przekazujesz, parallel
tak jak w przypadku polecenia env
lub xargs
, ale wiersz poleceń powłoki (tak jak w przypadku eval
polecenia).
Podobnie jak eval
w przypadku parallel arg1 arg2
, parallel
łączenie tych argumentów ze spacjami pomiędzy nimi (tak się staje arg1 arg2
) i ten ciąg znaków jest przekazywany do <the-shell> -c
.
W przypadku argumentów przekazywanych na parallel
standardowe wejście, parallel
przytacza je w formacie oczekiwanym przez tę konkretną powłokę (zadanie trudne i podatne na błędy, dlatego odkryto, że naprawiono wiele błędów wokół tego w parallel
dzienniku zmian ( niektóre nadal nie są naprawione na dzień 2017-03-06)) i dołącza to do tego wiersza poleceń.
Na przykład, jeśli zostanie wywołany od wewnątrz bash
,
echo "foo'bar" | parallel echo foo
Musiałby równoległego połączenia bash -c
ze echo foo foo\'bar
jak w wierszu poleceń. A jeśli zostanie wywołany z wewnątrz rc
(lub z PARALLEL_SHELL=rc
) za rc -c
pomocą echo foo foo''''bar
.
W Twoim:
parallel bash -c 'echo :\$1' '' {}
parallel
łączy te argumenty, które dają:
bash -c echo :$1 {}
Z {}
rozwiniętym i cytowanym w odpowiednim formacie dla powłoki, z której dzwonisz parallel
, przekazujesz to, do <that-shell> -c
którego zadzwonisz za bash -c echo
pomocą :$1
in $0
i bieżący argument w $1
.
To nie tak parallel
działa. Tutaj prawdopodobnie chcesz:
printf '1\n2\n' | PARALLEL_SHELL=bash parallel 'echo :{}'
Aby zobaczyć, co parallel
robi, możesz uruchomić go pod strace -fe execve
(lub odpowiednikiem w swoim systemie, jeśli nie Linux).
Tutaj możesz użyć GNU xargs
zamiast parallel
uzyskać łatwiejsze przetwarzanie bliższe oczekiwaniom:
printf '1\n2\n' | xargs -rn1 -P4 bash -c 'echo ":$1"' ''
Zobacz także dyskusję na https://lists.gnu.org/archive/html/bug-parallel/2015-05/msg00005.html
Zauważ bash -c 'echo foo' '' foo
, że $0
wewnątrz tworzysz pusty ciąg dla tego skryptu wbudowanego. Unikałbym tego, ponieważ $0
jest to również wykorzystywane w komunikatach o błędach. Porównać:
$ bash -c 'echo x > "$1"' '' /
: /: Is a directory
z.
$ bash -c 'echo x > "$1"' bash /
bash: /: Is a directory
Należy również pamiętać, że pozostawienie zmiennych bez cudzysłowu ma bardzo szczególne znaczenie bash
i na echo
ogół nie można ich używać w przypadku dowolnych danych.