问题
Inspired by Stack Overflow question Idomatic batch processing of text in Emacs? I tried out an Emacs shell script with the following headline:
#!/usr/bin/emacs --script
I put some Emacs Lisp code in it, and saved it as textfile rcat.
Since the --script option does not prevent the loading of the site-start file, I had a lot of
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
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?
回答1:
You could always change #!/usr/bin/emacs
to something like #!/home/thorsten/bin/emacs-no-site-file
, and set that up as:
#!/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.
回答2:
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.
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.
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.
#! /bin/sh
":"; exec emacs --no-site-file --script "$0" -- "$@" # -*-emacs-lisp-*-
(print (+ 2 2))
回答3:
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.
Let's assume you have a file named "test-emacs-script.el" with the following content:
#!/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:
("-a")
Unknown option `-a'
Resetting "argv" gets rid of "unknown option" error message
来源:https://stackoverflow.com/questions/6238331/emacs-shell-scripts-how-to-put-initial-options-into-the-script