Reputation: 8485
I'm experimenting with Emacs Lisp as an alternate shell scripting language, but ran into a weird issue. I wrote the following Emacs Lisp script, in a file called hello.el
and then made it executable:
#!/usr/local/bin/emacs --script
(princ "hello world\n")
When I ran it I got the following:
$ ./hello.el
./hello.el: line 2: princ: command not found
After some experimentation, I discovered that the code below the #!
is being run by Bash, or at least some other shell, and not Emacs:
#!/usr/local/bin/emacs --script
foo=bash?
echo $foo
ls -l | sort | tail -1
$ ./hello.el
bash?
total 7984
This seems pretty weird to me, since there's a lot of references to this --script
option in various Emacs docs, and when I run the script directly using this it works fine (i.e. when I paste /usr/local/bin/emacs --script hello.el
into my terminal.
What's really weird is that this script works exactly as expected:
#!/usr/bin/emacs --script
(princ "hello world\n")
But the reason I'm using /usr/local/bin/emacs
is that it's a newer version; the version at /usr/bin/emacs
is the Apple provided Emacs that comes with Mac OS X, while the one in /usr/local/bin/emacs
is installed via brew and much more recent (Emacs 24 vs 22).
What's going wrong here? Did something change between Emacs 22 and 24?
Upvotes: 2
Views: 840
Reputation: 8485
So I wrote that question up and got to the bit about Mac OS X before realizing what the problem was, and figured I might as well post the answer here since it's a bit mysterious. Hope it helps.
The problem is that /usr/local/bin/emacs
is a symlink pointing not to an Emacs binary, but to a shell script:
$ ls -l /usr/local/bin/emacs
lrwxr-xr-x 1 aki staff 30 May 20 2013 /usr/local/bin/emacs -> ../Cellar/emacs/24.3/bin/emacs
$ file /usr/local/Cellar/emacs/24.3/bin/emacs
/usr/local/Cellar/emacs/24.3/bin/emacs: Bourne-Again shell script text executable
$ cat /usr/local/Cellar/emacs/24.3/bin/emacs
#!/bin/bash
/usr/local/Cellar/emacs/24.3/Emacs.app/Contents/MacOS/Emacs -nw "$@"
I don't know why #!/path/to/a/shell/script
fails to "do the right thing". I experimented with it and it appears to just run your first script as a shell script rather than pass the name of the script to the first as an argument, as you'd expect. Maybe some shell wizard could comment on this?
In the meantime, this works:
#!/usr/local/Cellar/emacs/24.3/bin/emacs-24.3 --script
(princ "hello world\n")
Since that's the path to the proper Emacs binary. I suppose you would want to do some nonsense with env
or whatever to make this portable.
Hope this helps someone else trying to do this on a Mac.
Upvotes: 4