XARGS передают несколько аргументов подпрограмме Perl? - PullRequest
1 голос
/ 18 мая 2019

Я знаю, как передать несколько аргументов с помощью xargs :

echo a b | xargs -l bash -c '1:$0 2:$1'

, и я знаю, как передать массив аргументов в подпрограмму моего модуля perl из xargs:

echo a b | xargs --replace={} perl -I/home/me/module.pm -Mme -e 'me::someSub("{}")'

Но я не могу получить несколько отдельных аргументов, переданных Perl с использованием этих долларовых ссылок (для удовлетворения подписи me::someSub):

echo a b | xargs -l perl -e 'print("$0 $1")'

Просто печатает:

-e

Итак, как мне получить аргументы оболочки: $0, $1, переданные в подпрограмму моего модуля perl?

Я знаю, что мог бы просто разграничить a;b, чтобы xarg {} мог быть обработан с помощью perl-разбиения, чтобы получить отдельные аргументы), но я также мог просто полностью обработать все STDIN с помощью perl.Вместо этого моя цель состоит в том, чтобы использовать perl -e, чтобы я мог явно вызывать нужную подпрограмму (вместо того, чтобы иметь какую-то предварительную обработку в сценарии, которая выясняет, какую подпрограмму вызывать и какие аргументы использовать на основе STDIN, чтобы избежать сценариярасходы на техническое обслуживание).

Ответы [ 2 ]

3 голосов
/ 18 мая 2019

Хотя аргументы bash доступны как $@ и $0, $1, $2 и т. Д., Аргументы Perl доступны через @ARGV. Это означает, что Perl эквивалент

echo a b | xargs -l bash -c 'echo "1:$0 2:$1"'

есть

echo a b | xargs -l perl -e'CORE::say "1:$ARGV[0] 2:$ARGV[1]"'

Тем не менее, не имеет смысла использовать xargs таким образом, потому что нет способа предсказать, сколько раз он вызовет perl, и нет способа предсказать, сколько аргументов он передаст perl каждый раз. У вас проблема XY , и вы не предоставили нам никакой информации, чтобы помочь нам. Может быть, вы ищете

perl -e'CORE::say "1:$ARGV[0] 2:$ARGV[1]"' $( echo a b )
2 голосов
/ 18 мая 2019

Я не уверен в деталях вашего проекта, поэтому я полагаю, что вам нужен однострочный Perl для использования переменных оболочки, которые видны в области, в которой он называется.

A perl -e'...' выполняет программу Perl , заданную в ''. Чтобы любые переменные из среды, в которой запускается эта программа - конвейер или сценарий оболочки - были доступны программе, их значения должны быть переданы ей. Способы сделать это с одной строкой изложены в в этом посте , и вот резюме.

Программа Perl получает аргументы, переданные ей в командной строке в массиве @ARGV. Таким образом, вы можете вызвать его в конвейере как

... | perl -e'($v1, $v2) = @ARGV; ...' "$0" "$1"

или как

... | xargs -l perl -e'($v1, $v2) = @ARGV; ...'

, если xargs действительно используется для подачи программы Perl на вход. В первом примере переменные заключаются в кавычки для защиты возможных интересных символов в них (пробелы, * и т. Д.) От интерпретации оболочкой, которая устанавливает и запускает perl-программу.

Если ввод содержит несколько строк для обработки и однострочник использует для него -n или -p, то распаковываете аргументы в BEGIN блоке

... | perl -ne'BEGIN { ($v1, $v2) = splice(@ARGV,0,2) }; ...'  "$0" "$1" ...

, который выполняется во время компиляции, поэтому перед циклом на входных строках предоставляется -n / -p. Аргументы, отличные от имен файлов, теперь удаляются из @ARGV, поэтому оставьте там только имена файлов для -n / -p, на случай, если ввод поступит из файлов.

Существует также элементарный механизм для переключателей командной строки в однострочном режиме через переключатель -s . Пожалуйста, смотрите ссылку выше для деталей; Я бы порекомендовал @ARGV над этим.

Наконец, ваш код вызова может установить переменные окружения , которые затем будут доступны программе Perl в %ENV. Однако это не похоже на то, что вы хотите.

Также см. этот пост для другого примера.

...