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

Aus*_*tin 9 curl scala

我正在尝试使用scala.sys.process._向curron的chronos服务器提交POST请求.因为命令参数中有空格,所以我使用的是Seq[String]变体cmd.!!

我正在构建命令:

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

如预期的那样产生

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)
Run Code Online (Sandbox Code Playgroud)

然而,运行这个似乎破坏了这个'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.
"
Run Code Online (Sandbox Code Playgroud)

我不明白.相比之下,调用cmd.mkString(" ")和复制+粘贴到终端可以正常工作.

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
Run Code Online (Sandbox Code Playgroud)

我已经尝试了-H参数的多种变体无济于事,对使用sys.process ._中的单引号的任何见解!我将不胜感激.

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

<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>
Run Code Online (Sandbox Code Playgroud)

(除了屠杀jsonHash,即:

[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
Run Code Online (Sandbox Code Playgroud)

yǝs*_*ǝla 16

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

而不是这个:

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

你需要写这个:

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

它将序列的每个元素作为参数放在命令行上.所以"-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)
Run Code Online (Sandbox Code Playgroud)


sam*_*est 11

大多数其他答案都有点冒险,使用以下技巧让Bash为你做所有报价处理等等

import scala.sys.process._

Seq("bash", "-c", bashLine) !
Run Code Online (Sandbox Code Playgroud)

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

作为String皮条客的方法(轻松复制粘贴)

import scala.sys.process._

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