shell emacs command-line elisp options

Emacs shell scripts: ¿cómo colocar las opciones iniciales en el script?



command-line elisp (3)

Inspirado en la pregunta de desbordamiento de pila ¿ Procesamiento por lotes de texto de Idomatic en Emacs? Probé un script de shell de Emacs con el siguiente título:

#!/usr/bin/emacs --script

Puse un poco de código de Emacs Lisp en él y lo guardé como archivo de texto rcat.

Dado que la opción --script no impide la carga del archivo de inicio del sitio, tuve muchos

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)...

mensajes en el shell Bash (stdout). Puedo evitar eso llamando

rcat --no-site-file

o

rcat -Q

pero no cambiando el título en el script:

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

¿Hay alguna forma de pasar opciones adicionales a Emacs dentro de dicho archivo de script en lugar de hacerlo más adelante en la línea de comandos?


Muchas variantes de Unix solo permiten un solo argumento al programa en la línea shebang. Triste pero cierto. Si usa #!/usr/bin/env emacs para no depender de la ubicación del ejecutable de emacs , no puede pasar ningún argumento.

El encadenamiento de scripts es una posibilidad en algunos sistemas, pero eso tampoco es compatible en todas partes.

Puede ir a la ruta tradicional de escribir un script políglota: un script que es tanto un script de shell como un script de Emacs Lisp (como Perl''s if $running_under_some_shell , por ejemplo). Seguro que se ve hackish, pero funciona.

Los comentarios de Elisp comienzan con ; , que en el shell separa dos comandos. Así que podemos usar una ; seguido de una instrucción de shell para cambiar a Emacs, con el código Lisp real comenzando en la siguiente línea. Sin embargo, a la mayoría de los shells no les gusta un comando vacío, por lo que necesitamos encontrar algo que tanto el shell como Emacs traten como un no-op, para poner antes del ; . El comando shell no-op es:; puede escribirlo ":" en lo que respecta al shell, y Emacs lo analiza como una constante en el nivel superior que también es un no-op.

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


Si ejecuta emacs en modo de secuencia de comandos, recomendaría restablecer la variable "argv" a nula al final de la secuencia de comandos, de lo contrario emacs intentará interpretar "argv" una vez que la secuencia haya finalizado.

Supongamos que tiene un archivo llamado "test-emacs-script.el" con el siguiente contenido:

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

Intente ejecutar este script como "./test-emacs-script.el -a". Si ejecuta este script sin restablecer "argv" (última línea en el script), la salida será:

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

Al restablecer "argv" se elimina el mensaje de error "opción desconocida"


Siempre se puede cambiar #!/usr/bin/emacs a algo como #!/home/thorsten/bin/emacs-no-site-file , y configurarlo como:

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

Si esto no funciona para usted, o si desea que su script sea portátil, consulte la respuesta de Gilles a continuación para obtener un enfoque más robusto (y un poco raro).