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