Emacs shell脚本 - 如何将初始选项放入脚本?

时间:2022-12-06 09:25:53

Inspired by Stack Overflow question Idomatic batch processing of text in Emacs? I tried out an Emacs shell script with the following headline:

灵感来自Stack Overflow问题Emacs中的文本Idomatic批处理?我尝试了一个Emacs shell脚本,标题如下:

#!/usr/bin/emacs --script 

I put some Emacs Lisp code in it, and saved it as textfile rcat.

我在其中放入了一些Emacs Lisp代码,并将其保存为textfile rcat。

Since the --script option does not prevent the loading of the site-start file, I had a lot of

由于--script选项不会阻止加载site-start文件,因此我有很多

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

messages in the Bash shell (stdout). I can prevent that by calling

Bash shell中的消息(stdout)。我可以通过打电话来阻止

rcat --no-site-file

or

要么

rcat -Q

but not by changing the headline in the script:

但不是通过更改脚本中的标题:

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

Is there a way to pass additional options to Emacs inside such a script file instead of doing it later on the commandline?

有没有办法在这样的脚本文件中将其他选项传递给Emacs,而不是稍后在命令行上执行?

3 个解决方案

#1


11  

You could always change #!/usr/bin/emacs to something like #!/home/thorsten/bin/emacs-no-site-file, and set that up as:

您可以随时将#!/ usr / bin / emacs更改为#!/ home / thorsten / bin / emacs-no-site-file,并将其设置为:

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

If this doesn't work for you, or if you wish your script to be portable, then see Gilles' answer below for a more robust (and slightly funky :) approach.

如果这对您不起作用,或者您希望脚本可移植,那么请参阅下面的Gilles答案,以获得更强大(并且稍微有点时髦:)的方法。

#2


34  

Many unix variants only allow a single argument to the program on the shebang line. Sad, but true. If you use #!/usr/bin/env emacs so as not to depend on the location of the emacs executable, you can't pass an argument at all.

许多unix变体只允许在shebang行上的程序有一个参数。伤心,但也是如此。如果您使用#!/ usr / bin / env emacs以便不依赖于emacs可执行文件的位置,则根本不能传递参数。

Chaining scripts is a possibility on some systems, but that too is not supported everywhere.

链接脚本在某些系统上是可能的,但是在任何地方都不支持。

You can go the time-honored route of writing a polyglot script: a script that is both a shell script and an Emacs Lisp script (like Perl's if $running_under_some_shell, for example). It sure looks hackish, but it works.

您可以使用历史悠久的编写多语言脚本的路径:一个既是shell脚本又是Emacs Lisp脚本的脚本(例如Perl's if $ running_under_some_shell)。它确实看起来很乱,但它确实有效。

Elisp comments begin with ;, which in the shell separates two commands. So we can use a ; followed by a shell instruction to switch over to Emacs, with the actual Lisp code beginning on the next line. Most shells don't like an empty command though, so we need to find something that both the shell and Emacs treat as a no-op, to put before the ;. The shell no-op command is :; you can write it ":" as far as the shell is concerned, and Emacs parses that as a constant at top level which is also a no-op.

Elisp注释以;开头,在shell中分隔两个命令。所以我们可以使用;然后是一个shell指令切换到Emacs,实际的Lisp代码从下一行开始。大多数shell不喜欢空命令,所以我们需要找到shell和Emacs视为无操作的东西,放在;之前。 shell no-op命令是:;就shell而言,你可以把它写成“:”,Emacs将它解析为*的常量,也是一个无操作。

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

#3


7  

If you run emacs in script mode, I would recommend to reset "argv" variable to nil in the end of your script, otherwise emacs will try interpret "argv" after script is finished.

如果您在脚本模式下运行emacs,我建议在脚本结束时将“argv”变量重置为nil,否则emacs将在脚本完成后尝试解释“argv”。

Let's assume you have a file named "test-emacs-script.el" with the following content:

假设您有一个名为“test-emacs-script.el”的文件,其中包含以下内容:

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

Try running this script as "./test-emacs-script.el -a". If you run this script without resettings "argv" (last line in the script) then the output will be:

尝试将此脚本作为“./test-emacs-script.el -a”运行。如果运行此脚本而不重置“argv”(脚本中的最后一行),则输出将为:

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

Resetting "argv" gets rid of "unknown option" error message

重置“argv”摆脱“未知选项”错误消息

#1


11  

You could always change #!/usr/bin/emacs to something like #!/home/thorsten/bin/emacs-no-site-file, and set that up as:

您可以随时将#!/ usr / bin / emacs更改为#!/ home / thorsten / bin / emacs-no-site-file,并将其设置为:

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

If this doesn't work for you, or if you wish your script to be portable, then see Gilles' answer below for a more robust (and slightly funky :) approach.

如果这对您不起作用,或者您希望脚本可移植,那么请参阅下面的Gilles答案,以获得更强大(并且稍微有点时髦:)的方法。

#2


34  

Many unix variants only allow a single argument to the program on the shebang line. Sad, but true. If you use #!/usr/bin/env emacs so as not to depend on the location of the emacs executable, you can't pass an argument at all.

许多unix变体只允许在shebang行上的程序有一个参数。伤心,但也是如此。如果您使用#!/ usr / bin / env emacs以便不依赖于emacs可执行文件的位置,则根本不能传递参数。

Chaining scripts is a possibility on some systems, but that too is not supported everywhere.

链接脚本在某些系统上是可能的,但是在任何地方都不支持。

You can go the time-honored route of writing a polyglot script: a script that is both a shell script and an Emacs Lisp script (like Perl's if $running_under_some_shell, for example). It sure looks hackish, but it works.

您可以使用历史悠久的编写多语言脚本的路径:一个既是shell脚本又是Emacs Lisp脚本的脚本(例如Perl's if $ running_under_some_shell)。它确实看起来很乱,但它确实有效。

Elisp comments begin with ;, which in the shell separates two commands. So we can use a ; followed by a shell instruction to switch over to Emacs, with the actual Lisp code beginning on the next line. Most shells don't like an empty command though, so we need to find something that both the shell and Emacs treat as a no-op, to put before the ;. The shell no-op command is :; you can write it ":" as far as the shell is concerned, and Emacs parses that as a constant at top level which is also a no-op.

Elisp注释以;开头,在shell中分隔两个命令。所以我们可以使用;然后是一个shell指令切换到Emacs,实际的Lisp代码从下一行开始。大多数shell不喜欢空命令,所以我们需要找到shell和Emacs视为无操作的东西,放在;之前。 shell no-op命令是:;就shell而言,你可以把它写成“:”,Emacs将它解析为*的常量,也是一个无操作。

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

#3


7  

If you run emacs in script mode, I would recommend to reset "argv" variable to nil in the end of your script, otherwise emacs will try interpret "argv" after script is finished.

如果您在脚本模式下运行emacs,我建议在脚本结束时将“argv”变量重置为nil,否则emacs将在脚本完成后尝试解释“argv”。

Let's assume you have a file named "test-emacs-script.el" with the following content:

假设您有一个名为“test-emacs-script.el”的文件,其中包含以下内容:

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

Try running this script as "./test-emacs-script.el -a". If you run this script without resettings "argv" (last line in the script) then the output will be:

尝试将此脚本作为“./test-emacs-script.el -a”运行。如果运行此脚本而不重置“argv”(脚本中的最后一行),则输出将为:

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

Resetting "argv" gets rid of "unknown option" error message

重置“argv”摆脱“未知选项”错误消息