For some time I’m playing with Clojure and finally I found something that I actually need to write for myself. I want to replace a couple of Bash scripts by JVM hosted Clojure. I know that Babashka or maybe other languages are more focused on projects like this but… I don’t write this for a client, just for myself to learn / have fun + create something useful.
Could you recommend please a library to execute binaries on Linux (only Linux)? Preferably Clojure but obviously Java is OK too.
These are my wishes for features ordered from the most important to the least important:
execute an Linux executable like /usr/bin/ls (I don’t want to run ls - just example) with a collection of arguments like ["-l" "/home/user/Downloads"]
capture stdout and stderr and exit code
possibility to pipe (stdin) into the executable like: echo 'user:I changed my password' | chpasswd
wait to finish or not when it can take longer to finish (find, rsync…)
execute over SSH, for example ssh computer1 rm -r /home/user/abc.pdf
stdin over SSH, for example cat foo.txt | ssh computer1 'cat > /tmp/bar.txt'
P.S. Thank you very much for this amazing community. I learned a lot just by googling site:clojureverse.org question ;-).
In addition to what sh does: shell also throws an exception when the exit code is non-zero. You can do this manually using the check function: (check (sh ...)).
sh and shell are blocking - they wait for the process to finish first. When you don’t want this, use process, the most low level function in babashka.process:
(def find-proc (process "find" "."))
@find-proc ;; deref waits for the process to finish
See the babashka.process docs for more details:
Note that clojure 1.12.0-alpha2 features a very similar process library under clojure.java.process.
The shell function is called exec there and the process function is called start over there. Note that the exec function in babashka.process does something very different: it replaces the parent process with the new process.