hugoduncan / babashka.process

Clojure wrapper for java.lang.ProcessBuilder

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

babashka.process

A Clojure wrapper around java.lang.ProcessBuilder.

Status: alpha, WIP, still in development, breaking changes will be made.

This code may end up in babashka but is also intended as a JVM library. You can play with this code in babashka today, by either copying the code or including this library as a git dep:

$ export BABASHKA_CLASSPATH=$(clojure -Sdeps '{:deps {babashka/babashka.process {:sha "6c348b5213c0c77ebbdfcf2f5da71da04afee377" :git/url "https://github.com/babashka/babashka.process"}}}' -Spath)
$ bb -e "(require '[babashka.process :refer [process]]) (process [\"ls\"])"

Use any later SHA at your convenience.

Example usage

user=> (require '[babashka.process :refer [process]])

Invoke ls:

user=> (-> (process ["ls"]) :out)
"LICENSE\nREADME.md\nsrc\n"

Invoke ls for different directory than current directory:

user=> (-> (process ["ls"] {:dir "test/babashka"}) :out)
"process_test.clj\n"

Set the process environment.

user=> (-> (process ["sh" "-c" "echo $FOO"] {:env {:FOO "BAR" }}) :out)
"BAR\n"

Output as stream:

user=> (-> (process ["ls"] {:out :stream}) :out slurp)
"LICENSE\nREADME.md\ndeps.edn\nsrc\ntest\n"

Exit code:

user=> (-> (process ["ls" "foo"]) :exit)
0

By default, process throws when the exit code is non-zero:

user=> (process ["ls" "foo"])
Execution error (ExceptionInfo) at babashka.process/process (process.clj:54).
ls: foo: No such file or directory

Prevent throwing:

user=> (-> (process ["ls" "foo"] {:throw false}) :exit)
1

Capture the error output as a string or stream:

user=> (-> (process ["ls" "foo"] {:throw false}) :err)
"ls: foo: No such file or directory\n"

user=> (-> (process ["ls" "foo"] {:throw false :err :stream}) :err slurp)
"ls: foo: No such file or directory\n"

When :wait is set false, the exit code is wrapped in a future:

user=> (-> (process ["ls" "foo"] {:throw false :wait false}) :exit deref)
1

Redirect output to stdout:

user=> (do (process ["ls"] {:out :inherit}) nil)
LICENSE		README.md	deps.edn	src		test
nil

Redirect output stream from one process to input stream of the next process:

(let [is (-> (process ["ls"] {:out :stream}) :out)]
  (process ["cat"] {:in is
                    :out :inherit})
    nil)
LICENSE
README.md
deps.edn
src
test
nil

Both :in and :out may contain objects that are compatible with clojure.java.io/copy:

user=> (with-out-str (process ["cat"] {:in "foo" :out *out*}))
"foo"

user=> (with-out-str (process ["ls"] {:out *out*}))
"LICENSE\nREADME.md\ndeps.edn\nsrc\ntest\n"

Forwarding the output of a process as the input of another process can also be done with thread-first:

(-> (process ["ls"])
    (process ["grep" "README"]) :out)
"README.md\n"

License

Copyright © 2020 Michiel Borkent

Distributed under the EPL License. See LICENSE.

About

Clojure wrapper for java.lang.ProcessBuilder

License:Eclipse Public License 1.0


Languages

Language:Clojure 100.0%