% 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как для команды envor xargs, а командная строка оболочки (как для evalкоманды).
Как eval, например parallel arg1 arg2, parallelобъединяет эти аргументы с пробелами между ними (так становится arg1 arg2) и эта строка передается <the-shell> -c.
Для аргументов, передаваемых в parallelstdin, parallelзаключите их в кавычки в формате, ожидаемом этой конкретной оболочкой (трудная и подверженная ошибкам задача, поэтому вы обнаружите, что было исправлено много ошибок, связанных с этим в parallelChangelog ( некоторые по-прежнему не исправлены по состоянию на 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с :$1in, $0и текущий аргумент in $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как правило, не может использоваться для произвольных данных.