leaflogo

Iowa Dave

Living and Learning

Run an Emacs Lisp Script from the Command Line

September 22, 2025

This article demonstrates one way to run an Emacs Lisp script from the command line. The script prepares some text, prints it out to the terminal then exits. A shell instruction cleans up the output.

I present the example here first. Afterward, I offer some remarks.

The Lisp Script

The Lisp code statements for the script are entered as plain text and saved in a file. The file will be made executable by the bash shell. The first line of the file is special, the so-called shebang line which tells bash to use Emacs to run it as a script.

#! /usr/bin/emacs --script
  
;; define a variable and assign a string to it
(setq howdy "Hey Howdy Hey!")

;; print that variable to the terminal
;; princ outputs the text in a human-friendly way
;; the optional item 't' directs output to the stdout stream
(princ howdy t)

;; terminate printing by sending a newline
;; the first optional item 't' directs output to the stdout stream
;; the second 't' ensures that only one newline gets sent
(terpri t t)

Figure 1: Emacs Lisp script designed to run on the command line

Execute the Script

The file was saved as howdy.el in the current directory then made executable and invoked on the command line. The output surprised me. My expected text appears alright; however, some unexpected lines precede it.

$ # Make it executable
$ chmod +x howdy.el
$ # Run it
$ ./howdy.el

Loading /etc/emacs/site-start.d/00debian.el (source)...
Loading /etc/emacs/site-start.d/50dictionaries-common.el (source)...
Loading debian-ispell (native compiled elisp)...
Loading /var/cache/dictionaries-common/emacsen-ispell-default.el (source)...
Loading /var/cache/dictionaries-common/emacsen-ispell-dicts.el (source)...
Hey Howdy Hey!
      
Figure 2: Executing the Lisp script

Clean Up the Output

It turns out that those Loading ... lines originate in the C code underying Emacs. They are being output through the stderr pathway, which goes to the command line window by default. Preventing them is not a practical consideration. They must be dealt with another way, if the user wants to avoid seeing the these lines.

Two methods shown below are available for suppressing the lines before they can be displayed. Both of them involve redirecting stderr.

The first way prevents display of all informational messages coming out of Emacs.

The second way adds a shell command designed to filter out only the Loading ... lines. It would still allow actual error messages to be displayed.

$ # Method 1: redirect stderr to the null device
$ ./howdy.el 2>/dev/null
Hey Howdy Hey!

$ # Method 2: redirect stderr to stdout then
$ #           pipe everything into grep
$ #           using the -v option
$ #           to remove the unwanted lines
$ ./howdy.el 2>&1 | grep -v '^Loading.*\.\.\.$'
Hey Howdy Hey!
      
Figure 3:Ways to suppress unwanted output

Remarks

I scoured the Web without finding a worked example like this one.

Documentation for the Lisp programming capabilities of Emacs dwell overwhelmingly on using Lisp to customize Emacs as a text editor. Not much is said in any prominent way about using it as a general-purpose scripting language for the command line.

That is too bad, because Emacs Lisp can easily serve that way, just like perl, python, ruby, javascript or any other scripted language.

Piecing together bits of insight from various online chat pages brought things into focus.

Emacs can execute a file containing Lisp statements as a shell script when it is invoked in so-called batch mode.

This mode is selected by, among other things, including the ‑‑script option when launching Emacs. The option is described all too briefly in the manual page for Emacs (man emacs).

Now I know a little bit about how to do it.

As a newcomer to Emacs and to Lisp, I struggled with the specialized vocabulary and the writing style in the official documentation sources, the so-called info files that come installed with the software.

The same material is available online; however, reading the locally-installed versions goes faster, after one learns to navigate info elisp. Speed helps, because there is so, so much to read.

Repeated reading builds vocabulary and increases familiarity with where to find answers. After a while the information begins to make better sense.

Newfound ability to write a Lisp program and then run it as a shell script motivates further learning. Thank Goodness for motivation, because I am just getting started.

The demonstration was developed using GNU Emacs version 28.2 on a PC running in a bash shell with a version of Debian Linux. I tried to keep it generic, so that it would not depend on any particular feature of hardware or operating system. I hope this trivial example may benefit some other other searcher like me.