0

I have a command like:

(clojure.java.shell/sh "curl" "https://somesite.com" "-F" "[email protected]")

and I want to create a function that will run standard shell commands I supply... something like this:

(defn run-shell-command [command]
  (clojure.java.shell/sh (clojure.string/split command #" ")))

so that I could call it like this:

(run-shell-command "curl https://somesite.com -F [email protected]")

but this throws:

Unhandled java.lang.IllegalArgumentException
   No value supplied for key: ["curl" "https://somesite.com" "-F" "[email protected]"]

How do I make this work?

(of course, open to better ideas for how to do this)

2
  • Splitting on whitespace is what Groovy does. And there are questions about it, why it does not work, every day on SO. Never split commands on whitespace - it works only for every simple cases. Use the "sh -c" approach as suggested. Commented Jul 12, 2019 at 6:48
  • Ah, ok... I didn't know that. I haven't gotten the sh -c to work yet, per my comment on the other reply that suggests it, but once I do I'll get it right. That said, I'm happy to have a function that apparently will run arbitrary shell commands from text (useful for copying commands from the interwebs). This seems much easier than converting these commands into, say, clj-http. But is this an anti-pattern of its own, in production say? Commented Jul 12, 2019 at 14:34

2 Answers 2

3

You can also use the underlying command processor to process the string. E.g. using bash:

(clojure.java.shell/sh "bash" "-c" command)

...wrap it in a function and hide the command processor if you wish:

(defn run-shell-command [command]
  (clojure.java.shell/sh "bash" "-c" command))

then you can use any bash shell commands. E.g.

(run-shell-command "for i in $(ls); do echo $i; done")
Sign up to request clarification or add additional context in comments.

Comments

2

Your question is a common one amongst beginner lispers: If we have a function accepting arguments, how can we apply the function on a list of these arguments?

(defn f [a b c] (+ a b c))

(def args [1 2 3])

The answer is, as hinted above, the apply method. The method applies a function to a list of arguments. So in the example above:

(= (f 1 2 3)
   (apply f args))

i.e

(defn run-shell-command [command]
  (apply clojure.java.shell/sh (clojure.string/split command #" ")))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.