Как расширить {} из xargs при замене процесса?

Я пытаюсь использовать gap версии 4.10 с xargs следующим образом:

$ echo 1 | xargs -I '{}' gap -b <( echo 'Display("{}");' ) <( echo 'QUIT;')

который возвращает

{}

Однако следует

1

Следующие работы

$ gap -b <( echo 'Display("123");' ) <( echo 'QUIT;')
123

Если у вас нет gap v4.10, вы можете заменить gap на cat и все равно увидеть мою проблему:

$ echo 1 | xargs -I '{}' cat <( echo 'Display("{}");' ) <( echo 'QUIT;')
Display("{}");
QUIT;

Как я могу добиться того, чтобы возвращаемое значение стало?

Display("1");
QUIT;

С моей точки зрения, это не имеет никакого отношения к пробелу, а является комбинацией xargs и подстановки процесса в оболочке. У меня zsh 5.7.1 и GNU bash 5.0.3. xargs — это GNU версии 4.8.0.

Примечания:

  • Моя мотивация заключается в том, что я хочу запустить скрипт разрыва параллельно с разными параметрами из оболочки.
  • gap версии 4.10 еще нет опции -c <expr> (коммит), которая позволила бы мне чтобы избежать использования подстановки процессов. Однако на вычислительном сервере есть только гэп версии 4.10.0.

person Hotschke    schedule 13.05.2021    source источник


Ответы (2)


Сами подстановки процессов разрешаются в имена файлов, а не в вывод команд внутри подстанции:

$ echo <(echo foo)
/dev/fd/63

В результате xargs никогда не видит {}. Он считывает 1 со своего стандартного ввода, но ни один из аргументов xargs не содержит {}, поэтому подстановки не происходит. Все, что у вас осталось, это один вызов gap, например

gap -b /dev/fd/63 /dev/fd/62  # The exact paths may differ

и gap, AFAICT, просто читает команды из этих файлов и выполняет их.

Если вы хотите выполнить команду Display("1"), вам нужно сначала создать ее, затем выполнить результат. Что-то вроде

 # Adjust gap as needed to read from standard input.
echo 1 | xargs -I '{}' echo 'Display("{}"); Quit;' | gap
person chepner    schedule 13.05.2021
comment
Спасибо за ваш ответ. Это мне очень помогло. - person Hotschke; 14.05.2021

Как указал @chepner, замена процесса выполняется оболочкой до того, как xargs выполнит замену {}, поэтому xargs никогда не видит {}.

Создание команды оболочки следующим образом решило это для меня:

echo 1 | xargs -I '{}' zsh -c "gap -b <( echo 'Display(\"{}\");' ) <( echo 'QUIT;')"
person Hotschke    schedule 13.05.2021
comment
На всякий случай carpentries-incubator.github.io/gap-lesson/discuss имеет другой сценарий, когда есть сценарий оболочки, вызывающий GAP (прокрутите до раздела «Советы и рекомендации»). На сервер можно поставить свой GAP? Версия GAP 4.10.0 датирована ноябрем 2018 года, ей более 2 лет. - person Alexander Konovalov; 14.05.2021
comment
Спасибо, что поделились ссылкой, она тоже полезна. На самом деле можно было бы добавить это как еще один ответ на этот вопрос. По поводу версии гэпа: пробовал установить свой гэп (версия 4.11.1) на сервер с linuxbrew. Компиляция работала, но когда я вызываю $ ~/.linuxbrew/bin/gap, я получаю сообщение об ошибке Illegal instruction. Я не уверен, где начать искать причину здесь. Незаконная инструкция не является очень конкретным сообщением. - person Hotschke; 15.05.2021
comment
Никогда не использовал linuxbrew - вы имеете в виду, что можете использовать github.com/gap-system/homebrew-gap с linuxbrew для установки в Linux — хорошо, если это так! Если это не работает, попробуйте установить из исходного кода как gap-system.org/Releases. /4.11.1.html объясняет. Если это не сработает, обратитесь за помощью по электронной почте в поддержку GAP (все равно там увижу). - person Alexander Konovalov; 15.05.2021
comment
Хи-хи-хи. Я тоже заметил это вчера вечером. В свое оправдание это было давно и затерялось в памяти. - person Hotschke; 16.05.2021