clojure.java.shell provides Clojure access to operating-system commands. Its main function, sh, starts a command as a separate process, waits for its exit code, and returns standard output, standard error, and the exit status as strings and a number. section 22.0 section 22.6
Configure process interaction with sh options and helper macros:
- Pass strings, files, streams, readers, or byte arrays through :in; use :in-enc for input encoding. section 22.6
- Interpret output with :out-enc, or use :bytes to retain raw output bytes instead of a string. section 22.6
- Override inherited environment variables with :env and choose the initial working directory with :dir. section 22.6
- Use with-sh-dir and with-sh-env for thread-local settings shared by multiple sh calls. section 22.6
Inspecting command output
After requiring sh, (sh "ls" "/usr/share/dict") returns a map such as {:exit 0, :out "README\nconnectives\n...", :err ""}. Read (:out result) for normal output and inspect :exit or :err for failures. section 22.6
(defn pipe [cmd1 & cmds] ; #1
(reduce
(fn [{out :out} cmd] ; #2
(apply sh (conj cmd :in out)))
(apply sh cmd1)
cmds))
(println
(:out
(pipe ; #3
["env"]
["grep" "-i" "java"])))
;; JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home
;; JAVA_MAIN_CLASS_61966=clojure.main
;; _=/usr/bin/java
;; LEIN_JAVA_CMD=java
;; JAVA_MAIN_CLASS_62001=clojure.main
A small pipe helper feeds one command's :out into the next command's :in, composing separate processes into a Unix-style pipeline. section 22.6
