% 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.
Для аргументів, що передаються на parallelstdin, 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як правило, не може використовуватися для довільних даних.