Чому GNU паралельно не працює з “bash -c”?


Відповіді:


11

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


4
Mon dieu! Це краща відповідь, ніж міг написати автор GNU Paralel.
Оле Танге
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.