Сценарии оболочки 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"