【问题标题】:Java ProcessBuilder cant run simple scriptJava ProcessBuilder 无法运行简单的脚本
【发布时间】:2012-09-04 20:17:21
【问题描述】:

我有test.sh,它调用了一些程序并且该程序输出了一些行。

我的需要是只捕获最后一行输出

所以如果我做简单的事情

bash test.sh | tail -n 1  ========> Command 1

然后我得到错误"Do you want output to go to | or to tail"

所以要解决上述问题,我愿意

(bash test.sh) | tail -n 1   =======> Command 2 

然后我得到简单的 1 行日志。到目前为止一切顺利。

现在我需要通过java程序调用上面的命令,所以我将'('作为第一个参数传递给ProcessBuilder,但它抱怨它无法理解'('作为第一个参数。

如何将Command 2 传递给ProcessBuilder 以获取日志的最后一行。

我对 bash 和 linux 不是很熟悉,所以请原谅我的无知。我什至不知道为什么我收到command 1 的错误。

【问题讨论】:

    标签: java linux bash shell processbuilder


    【解决方案1】:

    您可以在此处重新排序以使其更容易。

    • 无需使用 tail 命令,因为您可以在读取 ProcessBuilder 输出时捕获最后一个命令。
    • 为确保您的脚本在 Java 应用程序调用它时运行,请确保 #!/bin/bash 出现在脚本的第一行。还要确保它是可执行的。

    这是一个改编自现有应用程序的代码,它将捕获最后一行。

    ProcessBuilder builder = new ProcessBuilder("test.sh");
    Process process = builder.start();
    InputStream is = process.getInputStream();
    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    String line;
    String lastLine = null;
    while ((line = br.readLine()) != null) {
    if (line != null) {
       lastLine = line;
    }
    }
    
    System.out.println(lastLine);
    

    【讨论】:

    • 我可以这样做,这是显而易见的答案,但如果程序输出数千行,那么它不是很有用。我不想遍历所有行:(
    • tail 命令真的做同样的事情吗?它是否有内部缓冲区并一一读取所有行?如果确实如此,那么我可以证明使用上述模式是合理的。
    • 你可以把你的命令和tail放在另一个脚本里:)
    • @user1631667 我必须实际查看(我只是在这里猜测)但它可能会寻找文件的末尾并向后工作,构建一个字符串直到它达到适当的行数.这在 Java 中是可能的,顺便说一句,使用 RandomAccessFileseek 方法。
    【解决方案2】:

    Java 的 ProcessBuilder(因此,Runtime.exec 方法)不支持管道 (|)、重定向 (>) 和运行多个命令 (&)。相反,您应该创建一个单独的脚本来调用您的 bash 脚本并将其通过管道传递给 tail:

    #!/bin/sh
    #tailLog.sh
    bash test.sh | tail -n 1
    

    然后在 Java 中:

    processBuilder.command("tailLog.sh");
    

    请记住,| 和其他 shell 标记特定于 shell,因此 Java 无法识别它们。

    【讨论】:

      【解决方案3】:

      要获取文件中的最后一行,请使用-

      $tail -1 filename.dat
      

      快速演示

      $ cat filename.dat
      Line 1
      Line 2
      Line 3
      Line 4
      End Line
      $ tail -1 filename.dat
      End Line
      

      【讨论】:

        【解决方案4】:

        好吧,既然您现在使用的是 Java,那么您可以使用它的“一次编写,到处运行”的特性。编写一个程序,打开一个文件,读取它的行,然后获取最后一个。它适用于任何平台。

        一个很好的类是BuffedReader

        【讨论】:

          最近更新 更多