% echo -e '1\n2' | parallel "bash -c 'echo :\$1' '' {}"
:1
:2
% echo -e '1\n2' | parallel bash -c 'echo :\$1' '' {}
%
Я б очікував, що другий рядок буде діяти так само.
% echo -e '1\n2' | parallel "bash -c 'echo :\$1' '' {}"
:1
:2
% echo -e '1\n2' | parallel bash -c 'echo :\$1' '' {}
%
Я б очікував, що другий рядок буде діяти так само.
Відповіді:
parallel
запускає команду в оболонці вже (що оболонка вона визначається з parallel
допомогою евристики (намір в тому , щоб викликати ту ж оболонку , як один parallel
був викликаний з ). Ви можете встановити $PARALLEL_SHELL
змінну для фіксації оболонки).
Це не команда, яку ви передаєте, parallel
як ви б для команди env
або xargs
команда, а командний рядок оболонки (як ви для eval
команди).
Як і в eval
, в parallel arg1 arg2
, parallel
це поєднує ці аргументи з пробілами між ними (так це стає arg1 arg2
) і до цього рядка передається <the-shell> -c
.
Для аргументів, що передаються на parallel
stdin, parallel
цитуйте їх у форматі, очікуваному саме цією оболонкою (складна задача і схильність до помилок, тому ви знайдете, що в цьому журналі було змінено чимало помилок у parallel
змінному журналі ( деякі досі не виправлені станом на 2017-03-06)) і додає його до цього командного рядка.
Наприклад, якщо зателефонували зсередини bash
,
echo "foo'bar" | parallel echo foo
Був би паралельний виклик bash -c
з echo foo foo\'bar
командним рядком. І якщо дзвонить зсередини rc
(або з PARALLEL_SHELL=rc
) rc -c
із echo foo foo''''bar
.
У вашому:
parallel bash -c 'echo :\$1' '' {}
parallel
поєднує ті аргументи, які дає:
bash -c echo :$1 {}
І з {}
розширено і цитуються в потрібному форматі для оболонки ви телефонуєте parallel
з, передає його в <that-shell> -c
який буде викликати bash -c echo
з :$1
в $0
і поточний аргумент в $1
.
Це не так, як parallel
працює. Тут ви, мабуть, захочете:
printf '1\n2\n' | PARALLEL_SHELL=bash parallel 'echo :{}'
Щоб побачити, що parallel
робить, ви можете запустити його під strace -fe execve
(або еквівалент у вашій системі, якщо не в Linux).
Тут ви можете використовувати GNU xargs
замість того, parallel
щоб надати більш просту обробку ближче до того, що ви очікуєте:
printf '1\n2\n' | xargs -rn1 -P4 bash -c 'echo ":$1"' ''
Дивіться також дискусію на веб- сайті https://lists.gnu.org/archive/html/bug-parallel/2015-05/msg00005.html
Зауважте, що в bash -c 'echo foo' '' foo
, ви створюєте $0
порожній рядок для цього вбудованого сценарію. Я б уникну, що $0
це також використовується в повідомленнях про помилки. Порівняйте:
$ bash -c 'echo x > "$1"' '' /
: /: Is a directory
з.
$ bash -c 'echo x > "$1"' bash /
bash: /: Is a directory
Також зауважте, що залишення змінних без котирування має дуже особливе значення, bash
і це, echo
як правило, не може використовуватися для довільних даних.