使用带单引号,空格,管道等的scala sys.process

时间:2014-01-21 01:48:29

标签: scala curl

我正在尝试使用scala.sys.process._通过curl向我的chronos服务器提交POST请求。因为命令参数中有空格,所以我使用Seq[String]的{​​{1}}变体

我正在构建命令:

cmd.!!

按预期产生

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

然而,运行它似乎会破坏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) 参数:

'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. " 和复制+粘贴到终端可以正常工作。

cmd.mkString(" ")

我已经尝试了-H参数的多种变体无济于事,在sys.process中使用单引号的任何见解。非常感谢。

我也试过这个变种,这会产生一系列错误,包括

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

(除了屠杀jsonHash,即:

<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>

3 个答案:

答案 0 :(得分:15)

您需要将每个参数拆分为序列的单独元素。

而不是:

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

你需要写下这个:

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

它将序列的每个元素作为参数放在命令行上。所以"-H 'Content-Type...看起来像是curl的一个参数,而它应该是2.

这是一种简单的测试方法:

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)

答案 1 :(得分:10)

其他大多数答案都有点过于繁琐,请使用以下技巧让Bash为您做所有报价处理等等

import scala.sys.process._

Seq("bash", "-c", bashLine) !

为了方便我自己搜索:bash执行进程sys.process管道字符串scala

作为String pimp方法(轻松复制粘贴)

import scala.sys.process._

implicit class PimpedString(bashLine: String) {
  def !!!: Int = Seq("bash", "-c", bashLine) !
}

答案 2 :(得分:2)

我也很难做到这一点。 Aleksey启发,下面为我工作。请注意,令人惊讶的是,Content-type没有额外引用(或双引号):

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