store/[org.clojure/clojure "1.8.0"] clj::clojure.java.shell/sh

Official Documentation

Add notes
Arities
==================================================
   [& args]

Docstring
==================================================
  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)

Source

(defn sh
  "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)"
  {:added "1.2"}
  [& args]
  (let [[cmd opts] (parse-args args)
        proc (.exec (Runtime/getRuntime) 
               ^"[Ljava.lang.String;" (into-array cmd)
               (as-env-strings (:env opts))
               (as-file (:dir opts)))
        {:keys [in in-enc out-enc]} opts]
    (if in
      (future
        (with-open [os (.getOutputStream proc)]
          (copy in os :encoding in-enc)))
      (.close (.getOutputStream proc)))
    (with-open [stdout (.getInputStream proc)
                stderr (.getErrorStream proc)]
      (let [out (future (stream-to-enc stdout out-enc))
            err (future (stream-to-string stderr))
            exit-code (.waitFor proc)]
        {:exit exit-code :out @out :err @err}))))

Example 1

Edit
(require '[clojure.java.shell :as shell])
;; => nil

(shell/sh "sh" "-c" "cd /etc; pwd")
;; => {:exit 0, :out "/etc\n", :err ""}

Example 2

Edit
(require '[clojure.java.shell :refer [sh]])
;; => nil

(println (:out (sh "cowsay" "Printing a command-line output")))
;; > 
;; >  _________________________________ 
;; > < Printing a command-line output. >
;; >  --------------------------------- 
;; >         \   ^__^
;; >          \  (oo)\_______
;; >             (__)\       )\/\
;; >                 ||----w |
;; >                 ||     ||
;; > 
;; => nil

Example 3

Edit
(require '[clojure.java.shell :refer [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
(println (:out (sh "cat" "-" :in "Printing input from stdin with funny chars like ' \" $@ & ")))
;; > Printing input from stdin with funny chars like ' " $@ & 
;; = nil

Example 4

Edit
(require '[clojure.java.shell :refer [sh]])
;; => nil

;; 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 \n characters in the middle.
(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 ""}

Example 5

Edit
(require '[clojure.java.sh :refer [shell]])
;; => nil

(sh "pwd" :dir "/home/ics/icsdev")
;; => {:exit 0, :out "/home/ics/icsdev\n", :err ""}

Uses on crossclj