Сценарии оболочки Emacs - как добавить в скрипт начальные параметры? - PullRequest
18 голосов
/ 04 июня 2011

Вдохновленный вопросом переполнения стека Идемная пакетная обработка текста в 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 ]

34 голосов
/ 07 июня 2011

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

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

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

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

#! /bin/sh
":"; exec emacs --no-site-file --script "$0" -- "$@" # -*-emacs-lisp-*-
(print (+ 2 2))
11 голосов
/ 05 июня 2011

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

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

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

7 голосов
/ 14 октября 2011

Если вы запускаете 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»

...