当前位置: 首页 > 知识库问答 >
问题:

在某些特定情况下,无法从ProcessBuilder的输入流中获得响应

申屠黎昕
2023-03-14

因此,我试图从linux获取电池状态,到目前为止,第一个命令(path变量)返回得很好,我能够从输入流中以序列的形式获得它的响应,但不幸的是,第二个命令(result变量)返回空序列。

fun getLinuxBatteryStatus(): Nothing? {
    val path = """upower --enumerate""".runCommand() ?: return null

    val parameters = listOf("present", "state", "energy-full", "energy", "energy-rate", "time to empty", "percentage")
    val result = """upower -i ${path.first { "battery_BAT" in it }} | grep -E "${parameters.joinToString("|")}""""
        .also { println(it) }
        .runCommand() ?: return null

    result.forEach(::println)   // <- no ouput
    // println(result.count())  // <- 0

    /* Do other thing and return something (that is not related to problem) */
}

输出:

upower -i /org/freedesktop/UPower/devices/battery_BAT1 | grep -E "present|state|energy-full|energy|energy-rate|time to empty|percentage"

上面的输出来自最后一个命令中的块,只是为了预览命令的字符串以便调试。如果我直接在终端中运行上面的命令,我将成功地得到如下响应:

    present:             yes
    state:               charging
    energy:              47.903 Wh
    energy-empty:        0 Wh
    energy-full:         50.299 Wh
    energy-full-design:  48.004 Wh
    energy-rate:         17.764 W
    percentage:          95%

为什么最后一个命令不工作(不返回任何响应)与ProcessBuilder?

注意:扩展函数runCommand取自此处

private fun String.runCommand(
    workingDir: File = File("."),
    timeoutAmount: Long = 60,
    timeoutUnit: TimeUnit = TimeUnit.SECONDS
): Sequence<String>? = try {
    ProcessBuilder(split("\\s".toRegex()))
        .directory(workingDir)
        .redirectOutput(ProcessBuilder.Redirect.PIPE)
        .redirectError(ProcessBuilder.Redirect.PIPE)
        .start()
        .apply { waitFor(timeoutAmount, timeoutUnit) }
        .inputStream.bufferedReader().lineSequence()
} catch (e: IOException) {
    e.printStackTrace()
    null
}

共有1个答案

白灿
2023-03-14

这里的问题是管道。

您试图运行一个管道——一个涉及运行多个程序的结构,需要一个shell来解释。

但是ProcessBuilder只运行一个程序。

您可以使用ProcessBuilder运行一个shell实例,然后它可以运行您的管道;请参阅此答案。

但是,在自己的代码中进行过滤,并避免完全调用grep,可能会更简单、更安全、更高效。

我建议捕获流程的错误输出,这很可能会让问题变得清楚。

 类似资料:
  • 问题内容: 我在文件Sandbox.java中具有以下类: Eclipse中的编译在第14行“无法推断map(Function)的类型参数”中显示错误。 使用纯javac(JDK 1.8.0_121)可以编译相同的代码而不会出现问题。 如果我将正确的行更改为: 然后代码将在Eclipse中编译而没有错误。 有谁知道为什么会有这样的行为?是虫子吗? 我使用Eclipse 4.6.2.20161208

  • 如果噪声对连续信道符号的影响是独立的,则可以用一组转换概率来描述。此概率就是发送符号i,收到符号j的概率。最大信道速率可用下式的最大值给出: 其中,我们改变,但保持。由拉格朗日方法可得到以下方程, 。 乘以,并针对s求得,可以证明。设的逆(如果存在的话)为,使得。则: 。 因此, 。 或: 。 这就是用于确定最大值的方程组,其中需要确定C,使得。在完成这一工作后,C为信道容量,是实现这一容量的信道

  • 问题内容: 我已经在带有Selenium和PhantomJS的Python中设置了一个简单的webscraping脚本。我总共要抓取大约200个URL。脚本最初运行良好,然后运行了大约20-30个URL(它可能会更多/更少,因为它失败时似乎是随机的,并且与任何特定的URL不相关),我在python中收到以下错误: 还有我的ghostdriver.log: 我进行了搜索,关于SO的大多数问题似乎都是

  • 我想用java代码调用一个外部程序,然后Google告诉我Runtime或ProcessBuilder可以帮助我完成这项工作。我试过了,结果发现java程序无法退出,这意味着子进程和父进程都将永远等待。它们要么挂起,要么陷入僵局。 有人告诉我原因是子进程的缓存太小了。当它试图将数据返回给父进程时,但是父进程没有及时读取它,然后他们两个都挂起了。所以他们建议我叉一个线程来负责读取子进程的缓存数据。我

  • 我用Kotlin和Jongo来访问MongoDB。Jongo使用Jackson来序列化/反序列化对象,以便从MongoDB中保存和读取它们。我使用Jackson-Kotlin模块来帮助使用构造函数序列化Kotlin数据类。 下面是一个序列化良好的数据类的示例: 下面是一个未能反序列化的类似类的示例: Jongo抛出以下异常,因为Jackson反序列化失败: 如果我像这样完整地注释会话数据类,它确实

  • 我有以下代码: 当我用java 8运行代码时,它可以工作。但对于java 11,它抛出了一个例外:java。时间总体安排DateTimeParseException:无法在索引3处分析文本“20 Janeiro 2021 00:26”。 我也有类似的情况,我要转换的字符串中有一个区域,代码是: 如果使用java 8运行,它仍然有效,但使用java 11则不行。异常是:java.time.forma