Система схем хитрости* с pdflatex -имя_работы

Я пытаюсь вызвать pdflatex из файла схемы обмана. Это команда Guile, которую я использую:

(system*
 "cat" "foo.txt" "|" "pdflatex" "-jobname" "\"bar\"")

Это ошибка, которую я получаю после запуска файла:

cat: invalid option -- 'j'
Try 'cat --help' for more information.

Если я запускаю команду из оболочки bash, она работает нормально.

cat foo.txt | pdflatex -jobname "bar"

-jobname — правильная команда для pdflatex, но system*, похоже, с ней проблема.

Я использую (GNU Guile) 2.2.4 и pdfTeX 3.14159265-2.6-1.40.20.


person 9716278    schedule 18.12.2019    source источник
comment
Это не выполнение команды оболочки, это запуск программы cat со всем остальным в качестве аргументов.   -  person Barmar    schedule 19.12.2019
comment
Таким образом, он не анализирует синтаксис оболочки, такой как |, для обозначения конвейера.   -  person Barmar    schedule 19.12.2019
comment
@Barmar Тогда я, должно быть, скучаю по system*. Я не думаю, что есть способ отправить строку из scm в pdflatex из scm без использования system*, поэтому я столкнулся с этой проблемой?   -  person 9716278    schedule 19.12.2019


Ответы (1)


Используйте system, а не system*. Он принимает одну строку в качестве аргумента и выполняет ее с помощью оболочки, которая выполнит требуемый конвейер.

(system "cat foo.txt | pdflatex -jobname 'bar'")

system* не использует оболочку. Как поясняется в руководстве:

system* похож на system, но принимает только одну строку на аргумент и не выполняет интерпретацию оболочки. Команда выполняется с помощью fork и execlp. Соответственно, эта функция может быть безопаснее, чем system, в ситуациях, когда интерпретация оболочки не требуется.

Обратите внимание, что ваша команда является бесполезным использованием cat, так как pdflatex принимает имя файла как аргумент. Вы можете использовать system*, чтобы выполнить его напрямую.

(system* "pdflatex" "-jobname" "bar" "foo.txt")

Кроме того, вам не нужно добавлять дополнительные кавычки вокруг bar при использовании system*; поскольку он не использует оболочку, он не анализирует специальные символы.

person Barmar    schedule 18.12.2019
comment
Хотя это может подойти для одноразового использования, обратите внимание, что использование system означает, что вам нужно не только точно знать, что содержит строка, но и точно знать, как ее интерпретирует оболочка. Это настолько сложно, что фактически невозможно. - person ; 22.12.2019
comment
@tfb Я добавил еще одну версию команды, которая не использует канал, поэтому можно использовать system* и избежать этой проблемы. - person Barmar; 22.12.2019
comment
Я не пытался обидеть ваш ответ, кстати: я думаю, что первый ответ подходит для случаев, когда вам все равно: более общий случай языка в строке - это то, что так ужасно. - person ; 25.12.2019
comment
Если бы у Guile был способ сделать конвейер на языке вместо вызова оболочки, это было бы оптимально. Я недостаточно хорошо знаю Гайла. - person Barmar; 26.12.2019
comment
Я тоже. Хотя, как вы указываете, вам здесь вообще не нужен канал, часто очень сложно быть таким же эффективным, как каналы в оболочке. Кажется, есть какой-то вариант popen, но если вы в конечном итоге получите поток, в который вы зацикливаете запись байтов, вы не сможете делать какую-либо магию, которую вы можете делать с вводом-выводом в современных ОС. - person ; 26.12.2019