有没有办法获取早期管道 Scala 进程 (#|) 的退出代码?

Posted

技术标签:

【中文标题】有没有办法获取早期管道 Scala 进程 (#|) 的退出代码?【英文标题】:Is there a way to get the exit code of an earlier piped Scala Process (#|)? 【发布时间】:2019-04-18 00:39:32 【问题描述】:

我正在尝试使用 scala 的 sys.process 库来传递命令,但我注意到 #| 将返回最终进程的退出代码。我在管道中的较早命令失败,但最终命令的退出代码为 0,因为它没有出错。

我想知道 scala 是否有办法检查/检索管道中先前的命令 (#|) 是否失败。

import scala.sys.process._
val p1 = ("false" #| "true").run()
assert(p1.exitValue == 1)

Bash 有 set -o pipefail 将传递管道的非零退出代码,但它看起来有点“hacky”:

val p2 = Seq("/bin/bash", "-c", "set -o pipefail && false | true").run()
assert(p2.exitValue == 1)

我希望有更好的方法。

谢谢,感谢您的帮助:)

【问题讨论】:

【参考方案1】:

!! 运算符在非零退出代码上抛出异常,因此它可能仅在成功时通过 #< 运算符将一个进程的输出传递到另一个进程的输入流。如果我们像这样定义一个自定义运算符#|<

  implicit class Pipefail[T](p1: T) 
    def #|<(p2: T)(implicit ev: T => ProcessBuilder): ProcessBuilder =
      Try(p1.!!).map(result => (p2 #< new ByteArrayInputStream(result.getBytes))).get
  

然后我们可以调用它

("false" #|< "true").run

应该抛出的

java.lang.RuntimeException: Nonzero exit value: 1

同时

("echo Beam Me Up, Scotty" #|< "tr a-z A-Z" #|< "grep -o SCOTTY" ).run

应该输出大写的SCOTTY。这将使用stringToProcess 隐式转换,所以记得import scala.sys.process._

【讨论】:

以上是关于有没有办法获取早期管道 Scala 进程 (#|) 的退出代码?的主要内容,如果未能解决你的问题,请参考以下文章

在命名管道 (FIFO) 的消费者端,有没有办法区分每个项目并将其重定向到自己的进程?

深刻理解Linux进程间通信(IPC)

linux系统的进程间通信有哪几种方式

linux系统的进程间通信有哪几种方式

进程间的通讯方式有几种?有啥优缺点

linux 下进程间的同步机制都有哪些