How to execute shell builtin from Scala

2019-03-20 04:35发布

I need to check some system settings like ulimit -n from Scala script in Linux. Had I to deal with ordinary commands I would use scala.sys.process package like:

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

Unfortunately this doesn't work for shell builtins. Is there any way to catch an output from shell builtin in Scala?

Update:

I tried the usual trick sh -c "ulimit -n" in several forms with no luck; All the commands below fail:

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

And I'm getting a runtime error in 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)

2条回答
该账号已被封号
2楼-- · 2019-03-20 05:09

Use

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

to mimic what the shell normally does when you enter sh -c 'ulimit -n'. That is, the command is sh and the arguments are -c and ulimit -n.

查看更多
别忘想泡老子
3楼-- · 2019-03-20 05:28

When strings are converted to a shell command, parameters are separated by space. The conventions you tried are shell conventions, so you'd need a shell to begin with to apply them.

If you want more control over what each parameter is, use a Seq[String] instead of a String, or one of the Process factories that amount to the same thing. For example:

Seq("sh", "-c", "ulimit -n").!!
查看更多
登录 后发表回答