Сценарии оболочки Emacs - как добавить в скрипт начальные параметры?

Вдохновленный вопросом переполнения стека Идомная пакетная обработка текста в Emacs? Я опробовал скрипт оболочки Emacs со следующим заголовком:

#!/usr/bin/emacs --script 

Я поместил в него какой-нибудь код Emacs Lisp и сохранил его как текстовый файл rcat.

Поскольку опция --script не препятствует загрузке файла запуска сайта, у меня было много

Loading /etc/emacs/site-start.d/20apel.el (source)...
Loading /etc/emacs23/site-start.d/35elib-startup.el (source)...
Loading /etc/emacs23/site-start.d/50auctex.el (source)...

сообщения в оболочке Bash (стандартный вывод). Я могу предотвратить это, позвонив

rcat --no-site-file

или же

rcat -Q

но не изменяя заголовок в сценарии:

 #!/usr/bin/emacs --script --no-site-file

Есть ли способ передать дополнительные опции в Emacs внутри такого файла сценария вместо того, чтобы делать это позже в командной строке?

3 ответа

Решение

Вы всегда можете изменить #!/usr/bin/emacs что-то вроде #!/home/thorsten/bin/emacs-no-site-fileи установите это как:

#!/bin/sh
exec /usr/bin/emacs --no-site-file "$@"

Если это не работает для вас, или если вы хотите, чтобы ваш сценарий был переносимым, то смотрите ответ Жиля ниже для более надежного (и слегка прикольного:) подхода.

Многие варианты unix допускают только один аргумент для программы в строке shebang. Грустно, но правда. Если вы используете #!/usr/bin/env emacs чтобы не зависеть от расположения emacs исполняемый файл, вы не можете передать аргумент вообще.

Цепные сценарии возможны в некоторых системах, но это также не поддерживается везде.

Вы можете пойти проверенным временем путем написания сценария полиглота: сценария, который является одновременно сценарием оболочки и сценарием Emacs Lisp (например, Perl if $running_under_some_shell, например). Это выглядит хакерски, но это работает.

Elisp комментарии начинаются с ;, который в оболочке разделяет две команды. Таким образом, мы можем использовать ; затем инструкция оболочки для переключения на Emacs, с фактическим кодом Lisp, начинающимся со следующей строки. Большинству оболочек не нравится пустая команда, поэтому нам нужно найти что-то, что и оболочка, и Emacs рассматривают как запрет, чтобы поставить перед ;, Команда shell no-op :; ты можешь написать это ":" что касается оболочки, и Emacs анализирует ее как константу на верхнем уровне, которая также не может использоваться.

#! /bin/sh
":"; exec emacs --no-site-file --script "$0" -- "$@" # -*-emacs-lisp-*-
(print (+ 2 2))

Если вы запускаете emacs в режиме сценария, я бы порекомендовал сбросить переменную "argv" в nil в конце вашего скрипта, иначе emacs попытается интерпретировать "argv" после завершения скрипта.

Предположим, у вас есть файл с именем "test-emacs-script.el" со ​​следующим содержимым:

#!/usr/bin/emacs --script
(print argv)
(setq argv nil)

Попробуйте запустить этот скрипт как "./test-emacs-script.el -a". Если вы запустите этот скрипт без сброса "argv" (последняя строка в скрипте), то результат будет:

("-a")
Unknown option `-a'

Сброс "argv" избавляет от сообщения об ошибке "unknown option"

Другие вопросы по тегам