I’m trying to launch external programs from Clojure and have come across two libraries that work very well to various degrees:
- clojure.java.shell
- GitHub - hozumi/clj-commons-exec: Apache Commons Exec wrapper for Clojure
Each provides a sh
function for executing programs together with arguments and allowing options such as providing environment variables.
Where they differ is that clj-commons-exec
allows you to specify an output stream to write to, whereas clojure.java.shell/sh
just returns all the output in one go in the return map.
For example:
(sh ["path/to/program"] {:out System/out})
will redirect output to System/out
.
This is particularly useful if I have a long running shell script and I want to see the output as it is printed in real-time, rather than having to wait until the whole script has finished running.
I can get clj-commons-exec
to work from within a Clojure REPL launched via clj
from a terminal, and I can also get it to work by launching a cider-nrepl
server again from a terminal and doing e.g. lein repl :connect <port>
using the port returned. However, when I try to do the same thing from within an emacs CIDER REPL, I only only see the final accumulated output rather than each message printed individually in real-time.
In case any of this isn’t clear, I’ve detailed it in an issue on the CIDER Github issues page, here:
It appears something is happening in CIDER but neither myself nor vemv
are entirely sure what it might be.
I’m wondering if anyone has any insights as to what might be causing this, and if there is any simple way of fixing it or working around it that doesn’t involve rewriting/forking any existing libraries.
For reference, clj-commons-exec
is a wrapper around Apache Commons Exec.