java - 从 java 调用 shell 脚本挂起

标签 java shell

因此,我正在尝试执行一个 shell 脚本,该脚本会从 Java 文件中生成大量输出(数百 MB)。 这会挂起进程并且永远不会完成。

但是,在 shell 脚本中,如果我将脚本的输出重定向到某个日志文件或/dev/null,Java 文件会立即执行并完成。

是因为 Java 程序永远无法完成的数据量大吗? 如果是这样,是否有任何此类文件?还是对数据量(记录)有任何限制?

下面是模拟此场景的方法。

Java 文件看起来像:

import java.io.InputStream;

public class LotOfOutput {

    public static void main(String[] args) {
        String cmd = "sh a-script-which-outputs-huuggee-data.sh"; 
        try {
            ProcessBuilder pb = new ProcessBuilder("bash", "-c", cmd);
            pb.redirectErrorStream(true);
            Process shell = pb.start();
            InputStream shellIn = shell.getInputStream();
            int shellExitStatus = shell.waitFor();
            System.out.println(shellExitStatus);
            shellIn.close();
        } catch (Exception ignoreMe) {
        }
    }
}

脚本“a-script-which-outputs-huuggee-data.sh”可能如下所示:

#!/bin/sh
# Toggle the line below
exec 3>&1 > /dev/null 2>&1

count=1
while [ $count -le 1000 ]
do
        cat some-big-file
        ((count++))
done

echo
echo Yes I m done

答对了就免费喝啤酒。 :)

最佳答案

这是因为您没有从 Process 的输出中读取。

根据 class' Javadocs ,如果你不这样做,那么你可能会陷入僵局;该进程填充其 IO 缓冲区并等待“shell”(或监听进程)从中读取并清空它。与此同时,本应执行此操作的进程正在阻塞等待进程退出。

您需要调用 getInputStream()并从中可靠地读取(可能从另一个线程)以停止进程阻塞。

另请查看 Five Java Process PitfallsWhen Runtime.exec() Won't - 两篇关于 Process 常见问题的信息性文章。

关于java - 从 java 调用 shell 脚本挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3425754/

相关文章:

c++ - 从 MFC(c++) 应用程序启动的可执行 jar 中获取返回值

c - 这个 shell 是做什么的?

java - 启动应用程序 spring-boot 后执行类中的某些方法

java - java中找不到路径名

java - Websocket onMessage中的android回调接口(interface)

android - 如何将内部 Android adb 连接到自身

bash - 如何在 macOS 终端中批量重命名文件?

java - 从android应用程序接收java servlet中的空值

java - Apache ANT Exec - 处理 exec/CakePHP 控制台提示

mysql - 如何从 Linux shell 脚本运行 MySQL 过程并将其输出存储在文件中