How can I execute system specific commands and get their response in Clojure? For example, let's assume we're on a Linux machine, how can I call top or free, and get their results for further processing?
4 Answers
(use '[clojure.java.shell :only [sh]])
(sh "free")
(sh "top" "-bn1")
See also: http://clojuredocs.org/clojure_core/clojure.java.shell/sh
6 Comments
sjac
Thanks for the example and link.
clojure.java.shell/sh works well on Linux machines, but not on Windows machines; is there a different shell for Windows?NielsK
I don't see any problem with Windows, (sh "calc") works normally on my system. As does (sh "notepad" "C:/windows/WindowsUpdate.log") . Whats the problem with this solution on your system ?
sjac
@NielsK: I had trouble calling the cmd prompt and passing it a command, i.e.
sh "cmd" "dir"Carl Smotricz
@sjac: To get the command processor to execute a command for you, you need to use the
/C option, i.e. (untested): sh "cmd" "/C" "dir". This is explained by (in the DOS window) help cmd.BillRobertson42
@PrayagUpd That sounds like a different question. You should ask it separately, and with more detail.
|
You should be able to use the Java Runtime.exec method as follows:
(import 'java.lang.Runtime)
(. (Runtime/getRuntime) exec "your-command-line-here")
The Runtime.exec method returns a Process object that you can query to get the standard output etc. as needed.
2 Comments
alhimik45
Dont forget to use array of string if command has arguments:
(. (Runtime/getRuntime) exec (into-array ["command" "arg1" "arg2"]))claj
In the most recent alphas of clojure 1.12.0 there is a java process api clojure.org/releases/devchangelog , CLJ-2759, in the namespace clojure.java.process github.com/clojure/clojure/blob/master/src/clj/clojure/java/…
If you are willing to get a little higher in term of abstractions (although no that high), I would recommend Conch, as I found it to make very readable code.
Comments
You could use the babashka library to run shell commands in Clojure. An example would be
#!/usr/bin/env bb
(require '[clojure.java.shell :refer [sh]])
(sh "top")