我需要从我的Scala代码执行外部二进制文件并获取其输出。执行此操作的标准方法似乎是使用scala.sys.process。以下代码主要有效:
import scala.sys.process._
val command = Seq("python3", "-c", "print('foo', end='')")
val result = command.!!
但是,似乎还有一个额外的尾随换行符:
print(result.length) // prints 4 instead of 3
print(result) // prints an extra newline at the end
我可以修改结果字符串以删除最后一个字符,但是sys.process会为输出添加一个尾随换行符似乎很奇怪,所以我认为它可能是我正在做的事情的错误或者是可以配置。
尾随的换行符应该在那里吗?
有没有办法在不操纵输出字符串的情况下摆脱它?
答案 0 :(得分:3)
你试过val result = cmd.lineStream
吗? (或相关的.lineStream_!
,它可以提供一些异常保护。)
结果是Stream[String]
。流的每个元素都是来自进程的输出字符串,其中保留了空格,但没有换行符,因为它是流元素分隔符。
添加的换行符似乎是针对使用!!
启动的流程而设计的。
def !! = slurp(None, withIn = false)
...
private[this] def slurp(log: Option[ProcessLogger], withIn: Boolean): String = {
val buffer = new StringBuffer
val code = this ! BasicIO(withIn, buffer, log)
if (code == 0) buffer.toString
else scala.sys.error("Nonzero exit value: " + code)
}
def apply(withIn: Boolean, buffer: StringBuffer, log: Option[ProcessLogger]) =
new ProcessIO(input(withIn), processFully(buffer), getErr(log))
...
def processFully(buffer: Appendable): InputStream => Unit =
processFully(appendLine(buffer))
...
private[this] def appendLine(buffer: Appendable): String => Unit = line => {
buffer append line
buffer append Newline <--!!
}
答案 1 :(得分:2)
sys.process
不是添加尾随换行符:echo
是。来自documentation:
说明 echo实用程序写入任何指定的操作数,用单个空格分隔(
') characters and followed by a newline (
\ n&#39;) 字符,标准输出。
使用trim
可以删除此内容。否则,如果你的shell支持它,你可以这样做:
val result = "echo -n foo".!!
答案 2 :(得分:1)
为了保留所显示的输出,您必须在进行任何NewLine解释(或添加)之前截取InputStream
。
import sys.process._
val cmnd = Seq("/bin/echo","-n","one\n\nthree")
val stdOutBuf = new StringBuilder
val pio = new ProcessIO(_.close() //ignore STDIN
,out=>{ //save STDOUT
val src = io.Source.fromInputStream(out)
src.foreach(stdOutBuf.+=)
src.close()
},_.close()) //ignore STDERR (or not, up to you)
val exitCode :Int = cmnd.run(pio).exitValue()
val exactOutput :String = stdOutBuf.result()