26

elisp is a good language, I find it can handle all kind of jobs, but can I use it like a shell script?

i.e. execute some *.el files from the console, without launching Emacs. Or launch Emacs, but don't enter interactive mode.

0

1 Answer 1

25

You can most definitely run elisp scripts in Emacs without starting the editor interface.

Here are the notes I've made/copied from a few extremely useful Q&As on the subject here at S.O. (and the following two in particular).

Much of this information, and more besides, is also covered in the following excellent overview, which is recommended reading:

;;;; Elisp executable scripts

;; --batch vs --script
;; M-: (info "(emacs) Initial Options") RET
;; M-: (info "(elisp) Batch Mode") RET

;; Processing command-line arguments (boiler-plate)
;; http://stackoverflow.com/questions/6238331/#6259330 (and others)
;;
;; For robustness, it's important to both pass '--' as an argument
;; (to prevent Emacs from trying to process option arguments intended
;; for the script), and also to exit explicitly with `kill-emacs' at
;; the end of the script (to prevent Emacs from carrying on with other
;; processing, and/or visiting non-option arguments as files).
;;
;; #!/bin/sh
;; ":"; exec emacs -Q --script "$0" -- "$@" # -*-emacs-lisp-*-
;; (pop argv) ; Remove the "--" argument
;; ;; (setq debug-on-error t) ; if a backtrace is wanted
;; (defun stdout (msg &optional args) (princ (format msg args)))
;; (defun stderr (msg &optional args) (princ (format msg args)
;;                                           #'external-debugging-output))
;; ;; [script body here]
;; Always exit explicitly. This returns the desired exit
;; status, and also avoids the need to (setq argv nil).
;; (kill-emacs 0)

;; Processing with STDIN and STDOUT via --script:
;; https://stackoverflow.com/questions/2879746/#2906967
;;
;; #!/bin/sh
;; ":"; exec emacs -Q --script "$0" -- "$@" # -*-emacs-lisp-*-
;; (pop argv) ; Remove the "--" argument
;; (setq debug-on-error t) ; if a backtrace is wanted
;; (defun stdout (msg &optional args) (princ (format msg args)))
;; (defun stderr (msg &optional args) (princ (format msg args)
;;                                           #'external-debugging-output))
;; (defun process (string)
;;   "Reverse STRING."
;;   (concat (nreverse (string-to-list string))))
;;
;; (condition-case nil
;;     (let (line)
;;       (while (setq line (read-from-minibuffer ""))
;;         (stdout "%s\n" (process line))))
;;   (error nil))
;;
;; ;; Always exit explicitly. This returns the desired exit
;; ;; status, and also avoids the need to (setq argv nil).
;; (kill-emacs 0)

Emacs aside, the only other elisp interpreter/compiler I'm aware of is Guile. If you're keen on general coding in elisp, that should be worth a look (especially if performance is a concern).

Sign up to request clarification or add additional context in comments.

3 Comments

Current URL for that article: lunaryorn.com/emacs-script-pitfalls
This link to the "Emacs script pitfalls" article seems to be dead too. Is this the same article?
Yep, that looks like the same one. This feels like the 4th or 5th time the 'official' URL for that article has stopped working. The Wayback Machine still retains it, at least: web.archive.org/web/20210724021036/https://lunaryorn.com/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.