22
votes

I would like to write a few Unix scripts in Emacs Lisp. However, there doesn't seem to be a clean way to write to STDOUT so I can redirect the results to a file or pipe the output to another command. The print function places double quotes around the output strings so I get "Hello world!" instead of Hello world!.

Here's the emacs script.

#!/usr/bin/emacs --script
;;
;; Run me from a Unix shell: ./hello.el > x.txt
;;
(message "Hello world!  I'm writing to STDERR.")
(print "Hello world!  I'm writing to STDOUT but I'm in quotes")
(insert "Hello world!  I'm writing to an Emacs buffer")
(write-file "y.txt")

And here's how I would like to call it.

hello.el > x.txt
hello.el | wc
2

2 Answers

24
votes

Seems like you want princ instead of print. So, basically:

(princ "Hello world! I'm writing to STDOUT but I'm not in quotes!")

However, one caveat is that princ does not automatically terminate the output with \n.

6
votes

As David Antaramian says, you probably want princ.

Also, message supports a format control string (akin to printf in C) that is adapted from format. So, you may eventually want to do something like

(princ (format "Hello, %s!\n" "World"))

As a couple of functions plus demonstration:

(defun fmt-stdout (&rest args)
  (princ (apply 'format args)))
(defun fmtln-stdout (&rest args)
  (princ (apply 'format
                (if (and args (stringp (car args)))
                    (cons (concat (car args) "\n") (cdr args))
                  args))))

(defun test-fmt ()
  (message "Hello, %s!" "message to stderr")
  (fmt-stdout "Hello, %s!\n" "fmt-stdout, explict newline")
  (fmtln-stdout "Hello, %s!" "fmtln-stdout, implicit newline"))