如何从Scala中执行Shell内置命令

8

我需要在Linux的Scala脚本中检查一些系统设置,比如ulimit -n。如果我要处理普通的命令,我会使用scala.sys.process包,就像这样:

import scala.sys.process._
println("ls -lha".!!)

不幸的是,这对于shell内置命令无效。有没有办法在Scala中捕获shell内置命令的输出?

更新:

我尝试了通常的技巧sh -c“ulimit -n”以多种形式,但都没有成功;以下所有命令都失败:

"sh -c 'ulimit -n'".!!
"sh -c \"ulimit -n\"".!!
"""sh -c "ulimit -n"""".!!
"""sh -c "ulimit -n """ + "\"".!!

我在REPL中遇到了运行时错误:

-n": 1: Syntax error: Unterminated quoted string
java.lang.RuntimeException: Nonzero exit value: 2
    at scala.sys.package$.error(package.scala:27)
    at scala.sys.process.ProcessBuilderImpl$AbstractBuilder.slurp(ProcessBuilderImpl.scala:131)
    at scala.sys.process.ProcessBuilderImpl$AbstractBuilder.$bang$bang(ProcessBuilderImpl.scala:101)
    at .<init>(<console>:11)
    at .<clinit>(<console>)
    at .<init>(<console>:11)
    at .<clinit>(<console>)
    at $print(<console>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
    at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
    at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
    at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
    at java.lang.Thread.run(Thread.java:722)

你在REPL以外的环境下尝试过吗,比如在Scala脚本中? - Malte Schwerhoff
2个回答

11

当字符串被转换为shell命令时,参数是通过空格分隔的。你尝试的规范是 shell 规范,因此你需要先有一个shell来应用它们。

如果你想要更多控制每个参数的内容,可以使用Seq[String]代替String,或者使用等效的Process工厂方法。例如:

Seq("sh", "-c", "ulimit -n").!!

5

使用

println( Process("sh", Seq("-c","ulimit -n")).!! )

为了模仿当您输入sh -c 'ulimit -n'时shell通常会执行的操作,需要执行以下命令:sh是命令,-culimit -n是参数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接