(sh & args)
Passes the given strings to Runtime.exec() to launch a sub-process. Options are :in may be given followed by any legal input source for clojure.java.io/copy, e.g. InputStream, Reader, File, byte[], or String, to be fed to the sub-process's stdin. :in-enc option may be given followed by a String, used as a character encoding name (for example "UTF-8" or "ISO-8859-1") to convert the input string specified by the :in option to the sub-process's stdin. Defaults to UTF-8. If the :in option provides a byte array, then the bytes are passed unencoded, and this option is ignored. :out-enc option may be given followed by :bytes or a String. If a String is given, it will be used as a character encoding name (for example "UTF-8" or "ISO-8859-1") to convert the sub-process's stdout to a String which is returned. If :bytes is given, the sub-process's stdout will be stored in a byte array and returned. Defaults to UTF-8. :env override the process env with a map (or the underlying Java String[] if you are a masochist). :dir override the process dir with a String or java.io.File. You can bind :env or :dir for multiple operations using with-sh-env and with-sh-dir. sh returns a map of :exit => sub-process's exit code :out => sub-process's stdout (as byte[] or String) :err => sub-process's stderr (String via platform default encoding)
user=> (use '[clojure.java.shell :only [sh]])
;; Note: The actual output you see from a command like this will look messier.
;; The output below has had all newline characters replaced with line
;; breaks. You would see a big long string with \
characters in the middle.
user=> (sh "ls" "-aul")
{:exit 0,
:out "total 64
drwxr-xr-x 11 zkim staff 374 Jul 5 13:21 .
drwxr-xr-x 25 zkim staff 850 Jul 5 13:02 ..
drwxr-xr-x 12 zkim staff 408 Jul 5 13:02 .git
-rw-r--r-- 1 zkim staff 13 Jul 5 13:02 .gitignore
-rw-r--r-- 1 zkim staff 12638 Jul 5 13:02 LICENSE.html
-rw-r--r-- 1 zkim staff 4092 Jul 5 13:02 README.md
drwxr-xr-x 2 zkim staff 68 Jul 5 13:15 classes
drwxr-xr-x 5 zkim staff 170 Jul 5 13:15 lib
-rw-r--r--@ 1 zkim staff 3396 Jul 5 13:03 pom.xml
-rw-r--r--@ 1 zkim staff 367 Jul 5 13:15 project.clj
drwxr-xr-x 4 zkim staff 136 Jul 5 13:15 src
", :err ""}
user=> (use '[clojure.java.shell :only [sh]])
user=> (println (:out (sh "cowsay" "Printing a command-line output")))
_________________________________
< Printing a command-line output. >
---------------------------------
\\ ^__^
\\ (oo)\\_______
(__)\\ )\\/\\
||----w |
|| ||
nil
user=> (use '[clojure.java.shell :only [sh]])
nil
;; note that the options, like :in, have to go at the end of arglist
;; advantage of piping-in thru stdin is less need for quoting/escaping
user=> (println (:out (sh "cat" "-" :in "Printing input from stdin with funny chars like ' \\" $@ & ")))
Printing input from stdin with funny chars like ' " $@ &
nil
;; sh is implemented using Clojure futures. See examples for 'future'
;; for discussion of an undesirable 1-minute wait that can occur before
;; your standalone Clojure program exits if you do not use shutdown-agents.
(sh "pwd" :dir "/home/ics/icsdev")
{:exit 0, :out "/home/ics/icsdev\
", :err ""}
(require '[clojure.java.shell :as shell])
(shell/sh "sh" "-c" "cd /etc; pwd")
{:exit 0, :out "/etc\
", :err ""}
;; note that you have to split you script by whitespace
;; that was confusing for me
;; for example script:
;; "terraform plan -var param1=value1 -var param2=value2 -var-file=/etc/var.tfvars"
(shell/sh "terraform" "plan" "-var" "param=value" "-var" "param2=value2" "-var-file=/etc/var.tfvars")