[For the Emacs mode for editing DOS batch files, see DosScripts.]

According to the EmacsManual:

: ''The command-line option `-batch' causes Emacs to run noninteractively.
In this mode, Emacs does not read commands from the terminal, it does
not alter the terminal modes, and it does not expect to be outputting
to an erasable screen.  The idea is that you specify Lisp programs to
run; when they are finished, Emacs should exit.'' [...]

: ''Any Lisp program output that would normally go to the echo area, either using message, or using prin1, etc., with t as the stream, goes instead to Emacs’s standard descriptors when in batch mode: message writes to the standard error descriptor, while prin1 and other print functions write to the standard output.
Similarly, input that would normally come from the minibuffer is read
from the standard input descriptor.  Thus, Emacs behaves much like a
noninteractive application program.''  [...]

The EmacsManual does not give any examples so here are a few.

== Basics ==

You can call simulate an EmacsLisp-based script by putting this in a batch script:

{{{
emacs -batch -l ~/.emacs.editor --eval="(require 'foo)" \
--eval="(require 'bar)" \
--eval="(some-function $*)"
}}}

Starting with the Emacs 22, you can write Emacs scripts
just as if you were writing Bash or Perl scripts, when you include
this at the top of your script file:

{{{
#!/usr/bin/emacs --script
}}}

When printing the following inside a bash script I had to escape the quotes!
{{{
echo emacs info: $(emacs  --batch --eval="(print (concat emacs-version \",build: \" (number-to-string emacs-build-number) \" on \" emacs-build-system))")

emacs info: "29.0.50,build: 4 on nb3"
}}}

==Error codes==

One use of batch scripting is to run a predicate over a collection of files. For example, to use 'check-parens' and exit with an error code 1 if 'check-parens' throws an exception:

{{{
emacs file --batch --eval="(condition-case nil (check-parens) (error (kill-emacs 1)))"
}}}

Easily turned into a shell script to print out the names of files with detected imbalances:

{{{
for file in *.txt; do emacs "$file" --batch --eval="(condition-case nil (check-parens) (error (kill-emacs 1)))" &> /dev/null || echo $file; done
}}}

==Abuse Emacs as an REPL==

Surely there's better way to use Emacs or REPL, but why not?

{{{
$ emacs --batch --eval "(while t (print (eval (read))))"
}}}

Now use the REPL
{{{
Lisp expression: (defun factorial (x) (if (> x 0) (* (factorial (1- x)) x) 1))

factorial
Lisp expression: (factorial 5)

120
}}}

Coincidentally pressing ^D has the normal behavior of quitting the REPL
{{{
Lisp expression: Error reading from stdin
$ 
}}}

==Indenting C files==

  emacs -batch sample.c --eval '(indent-region (point-min) (point-max) nil)' -f save-buffer

The above opens the file ##sample.c## and runs `indent-region' from the
beginning (`point-min') to the end (`point-max') of the file, then
saves the file.  Because Emacs is thoughtful, it automatically saves a
copy of the original file to ##sample.c~##.

[:fill]
==Filling Paragraphs==

Emacs is provided with an intelligent paragraph filling command, which
can be helpful for use on numerous files.  To have Emacs fix the long
lines of one or more files from the command-line, use the following
command:

  emacs -batch long-file.txt --eval '(fill-region (point-min) (point-max))' -f save-buffer

Emacs will use the filling rules for the mode the file is opened in,
and fill all lines in the file.  ''This could have unexpected results
in certain modes.''

Here is a link to a script that wraps up the command so it can be
conveniently used on the command line with command line arguments:

* http://www.cslab.pepperdine.edu/warford/BatchIndentationEmacs.html

[:texinfo]
==Texinfo Files==

Emacs can, from the command-line, update or insert [[Texinfo]] menus
and nodes in a Texinfo document using the `texinfo-every-node-update'
and `texinfo-all-menus-update' commands.  This is especially helpful
when a Texinfo file is being generated or converted from another
source document.  Consider the following MakeFILE rule which can
convert some ''OTHER'' format into Texinfo (where ''OTHER'' is some
other document format like XML or HTML):

  %.texi: %.other $(OTHER2TEXI)
          $(OTHER2TEXI) $< > $@
          emacs -batch $@ \
           -f texinfo-every-node-update -f texinfo-all-menus-update \
           -f save-buffer

==Shell Script==

The example script shs-example demonstrates all the things you'd want
to do with emacs scripts, and is meant to serve as a tutorial (I am
teaching myself and improvements are very welcome) as well as
demonstrate some useful functions from shs.el.  Save these files
somewhere in your bash path, change the path to that path in
example-emacs-script and change the "#/usr/local/bin/emacs" address
call to that of your actual Emacs path.  Then, on bash prompt, type
example-emacs-script.


* http://www.gnufans.net/~deego/emacspub/lisp-mine/shs/dev/shs.el
* http://www.gnufans.net/~deego/emacspub/lisp-mine/shs/dev/shs-example
* http://www.gnufans.net/~deego/emacspub/lisp-mine/shs/dev/shs-example-fn.el

(Note: Unfortunately these links are all dead. Wouldn't be possible to put the code on EmacsWiki itself?)

(See: 
* https://web.archive.org/web/20080924142017/http://www.gnufans.net:80/~deego/emacspub/lisp-mine/shs/dev/shs.el 
* https://web.archive.org/web/20080924142017/http://www.gnufans.net/~deego/emacspub/lisp-mine/shs/dev/shs-example
* https://web.archive.org/web/20080924142017/http://www.gnufans.net/~deego/emacspub/lisp-mine/shs/dev/shs-example-fn.el )

(See: https://lists.gnu.org/archive/html/gnu-emacs-sources/2005-01/msg00013.html)

If active Emacs developers are reading this, we'd like to point out that
(princ) in batch-mode prints to stdout, as opposed to stderr, which is
not what the EmacsLispReference says.  On the other hand, that is the only
way at this time (we think) that you can print to stdout through an
emacs batch script, so we hope that this "bug" is not fixed, but
retained as a feature. 

This is not a bug. princ function and all the print functions) direct their output
depending on the variable standard-output. This variable can be set to a buffer, a marker,
any function of 1 argument or the symbol t. The last case is the default. In interactive
mode the output goes to the echo area. In batch mode it is directed to the normal stdout.
The message function prints to stderr in batch mode. Perhaps there is an error in the
documentation you referenced above (I have not checked)

''It seems to have been corrected:''
: ''Any Lisp program output that would normally go to the echo area, either using message, or using prin1, etc., with t as the stream, goes instead to Emacs's standard descriptors when in batch mode: message writes to the standard error descriptor, while prin1 and other print functions write to the standard output.''

==Prompts in w32 cmd-files==
Example:

{{{
@"c:\Program Files\Emacs\emacs-21.3\bin\emacs.exe" -batch -no-site-file -q ^
  -eval "(unless (y-or-n-p \"Do you want to continue? \") (kill-emacs 1))

@if %errorlevel% GTR 0 goto fin
}}}


== Using packages in your script ==

Emacs batch mode does not read your personal config (or any config, it's equivalent to -Q) so you don't get packages loaded. 

You can do whatever you were going to do though, just {{{package-initialize}}} when you eval. Here's how I build packages using ElpaKit, which is itself a package:

{{{
emacs -batch --eval '(progn(package-initialize)(elpakit-make-multi "~/work/elmarmalade"))'
}}}

Nothing else special is required, except the package directory (which is {{{~/.emacs.d/elpa}}}) to be in the //normal// place.

It does seem that this would be a useful additional startup option, batch but with your packages and not your config.

==Passing args to emacs lisp functions from the command line==
If an interactive function takes an argument, Emacs will print the minibuffer prompt and wait for input at the command line. But if you give it something on STDIN, Emacs will use that instead. So you can have a script like
{{{
#!/bin/sh
echo "$@" | emacs --batch -l ~/.emacs.d/lisp/mything.el -f mything
}}}

that can be called like `mything.sh "here's some input"` to have "here's some input" passed to the mything function defined in mything.el. I used to maintain two versions of some things for use from emacs and from command line but now porting everything to elisp and making stub scripts like this.

You can also access the variable {{{command-line-args-left}}} to read any arguments that have not been processed yet.

==Discussion==

We need a term more descriptive than "scripting" for this, since some people
think that writing an emacs package is scripting.  "batch mode" kind of
implies no interactivity, which isn't true.  "command line or executable
scripting with emacs lisp" is a mouthful.  Maybe "scripting" is the best.

[new]
Scripting is within a hair of opening up a huge new market for emacs.  People
who use bash or Python or whatever could be using emacs:

* you're already using it
* it's lisp
* it's pretty cl compatible
* it's already installed
* it's portable
* it does everything
* it won't go away
* it supports unique features like buffers
* you can record a keyboard macro and save the script

The EASILY FIXABLE THINGS holding it back are:

* fear that emacs lisp isn't a real language (as if bash were)
** some people don't know about (require 'cl) or lexical-let
* uncertainty about whether it will handle stdio and the like
** how to get rid of "Loading" messages?
** how to pipe something to a command and back to emacs lisp?
** is "a few minor exceptions" above famous last words?
* doubt that this usage will be supported
** see note about princ above
** no detailed discussion in documentation
** paucity of open source shebang scripts

Does anybody agree?  Drop me a line just to let me know somebody read this.

(gambarimasu who is at gmail.com)

==See also==

See also EmacsScripts.

----
CategoryCode
