Using scala sys.process with single quotes, spaces, pipes, etc.

I am trying to use scala.sys.process._ to send a POST request to my chronos server with curl, because there is a space in the command arguments, I use the Seq[String] cmd.!! option cmd.!!

I create a command as follows:

 val cmd = Seq("curl", "-L", "-X POST", "-H 'Content-Type: application/json'", "-d " + jsonHash, args.chronosHost + "/scheduler/" + jobType) 

which produces, as expected,

 cmd: Seq[String] = List(curl, -L, -X POST, -H 'Content-Type: application/json', -d '{"schedule":"R/2014-02-02T00:00:00Z/PT24H", "name":"Scala-Post-Test", "command":"which scalac", "epsilon":"PT15M", "owner":"myemail@thecompany.com", "async":false}', localhost:4040/scheduler/iso8601) 

however, running this function will distort the argument 'Content-Type: application/json' :

 scala> cmd.!! % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 264 0 100 100 164 2157 3538 --:--:-- --:--:-- --:--:-- 54666 res21: String = "The HTTP header field "Accept" with value "*/* 'Content-Type:application/json'" could not be parsed. " 

which I do not understand. On the contrary, calling cmd.mkString(" ") and copying + pasting into the terminal works as expected.

 curl -L -X POST -H 'Content-Type:application/json' -d '{"schedule":"R/2014-02-02T00:00:00Z/PT24H", "name":"Scala-Post-Test", "command":"which scalac", "epsilon":"PT15M", "owner":"austin@quantifind.com", "async":false}' mapr-01.dev.quantifind.com:4040/scheduler/iso8601 

I tried numerous variations on the -H argument to no avail, any understanding of using single quotes in sys.process._ !! will be greatly appreciated.

I also tried options that generate a lot of errors, including

 <h2>HTTP ERROR: 415</h2> <p>Problem accessing /scheduler/iso8601. Reason: <pre> Unsupported Media Type</pre></p> <hr /><i><small>Powered by Jetty://</small></i> 

(in addition to jsonHash splitting, i.e.:

 [1/6]: '"schedule":"R/2014-02-02T00:00:00Z/PT24H"' --> <stdout> curl: (6) Couldn't resolve host ''"schedule"' Which makes me think it is not interpreting the -H argument correctly 
+8
scala curl
source share
3 answers

You need to break each argument into a separate element of the sequence.

Instead of this:

 val cmd = Seq("curl", "-L", "-X POST", "-H 'Content-Type: application/json'", "-d " + jsonHash, args.chronosHost + "/scheduler/" + jobType) 

you need to write this:

 val cmd = Seq("curl", "-L", "-X", "POST", "-H", "'Content-Type: application/json'", "-d " + jsonHash, args.chronosHost + "/scheduler/" + jobType) 

It puts each element of the sequence as an argument on the command line. Therefore, "-H 'Content-Type... looks like a single curl argument, whereas it should be 2.

Here is an easy way to test:

 import scala.sys.process._ val cmd = Seq("find", "/dev/null", "-name", "null") // works // does not work: val cmd = Seq("find", "/dev/null", "-name null") val res = cmd.!! println(res) 
+14
source share

Most of the other answers are a bit awkward, use the following trick to get Bash, to do all the processing of quotes, etc. etc. for you.

 import scala.sys.process._ Seq("bash", "-c", bashLine) ! 

To simplify Googling: Bash itself, execute the sys.process pipe string scala process

Like the String Pimp Method (Simple Copy)

 import scala.sys.process._ implicit class PimpedString(s: String) { def !!!: Int = Seq("bash", "-c", bashLine) ! } 
+6
source share

It was also difficult for me to do this job. Enlightened by Alexei, he worked for me below. Note that, unexpectedly, there is no extra quote (or double quote) for the Content-type:

 val deploy = Seq("curl", "-X", "POST", s"$ip/v2/apps", "-H", "Content-Type: application/json", "-d", s"@$containerJson") println(deploy.!!) 
+2
source share

All Articles