【问题标题】:Unix Script not working in Java Process Runtime.exec()Unix 脚本在 Java Process Runtime.exec() 中不起作用
【发布时间】:2009-11-14 06:35:51
【问题描述】:

我正在 Spring Web MVC 中开发一个应用程序,我需要在其中执行一些 linux 脚本..

我正在使用 tomcat 5.5 版在 linux 中运行我的项目..

我的代码是这样的:

Process proc = runtime.exec("sudo cp /var/tmp/mailserverfiles/editinterface.txt /etc/sysconfig/network-scripts/editinterface.txt");
InputStream inputstream = proc.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
String line;
while ((line = bufferedreader.readLine()) != null) {
    System.out.println("\nOUTPUT = " + line);
}
System.out.print("\nbefore execute6");
try {
    if (proc.waitFor() != 0) {
       System.err.println("\nexit value = " + proc.exitValue());
    }
} catch (InterruptedException e) {
       System.err.println("\nERROR = " + e);
}

在这里,我想使用 linux 脚本将特定文件从一个位置复制到另一个位置..

但是当我执行这部分时,我得到了

exit value = 1

作为输出.. 我也尝试将此脚本放入 .sh 文件并尝试从 Java 代码执行该 shell 脚本,但我得到相同的结果..

谁能告诉我,这应该是什么原因?

提前谢谢..

【问题讨论】:

    标签: java linux unix tomcat


    【解决方案1】:

    我猜sudo 期待一个交互式终端来询问密码。由于没有交互式终端,它会向 stderr 打印一条错误消息并以退出代码 1 退出。您没有读取错误流,因此您不会看到它可能打印的任何消息。

    在任何情况下,您肯定都想阅读错误流。现在这样做将帮助您诊断此时出现的问题。

    【讨论】:

    • 在简单的情况下,例如“cp /tmp/editinterface.txt /tmp/editinterface1.txt”,它也不起作用..来自 .exec()。
    • 我不准备相信您正在运行的命令以退出值 1 退出 并且 根本不会向 stdout 或 stderr 打印任何内容。如果你不做所有 BufferedReader 的事情,直接从 InputStream 中读取会发生什么?
    • 当我直接从 proc 的 inputStream 读取时,它给了我-1。
    【解决方案2】:

    我假设运行 Tomcat 的用户可以不受限制地访问 sudo?并且没有提示输入密码?

    【讨论】:

      【解决方案3】:

      可能是你的搜索路径很奇怪,当你尝试执行命令时没有找到“cp”和“sudo”。

      以下是您可以尝试找出问题的一些方法:

      • 尝试运行不带“sudo”的“cp”命令。

      • 尝试给出命令的完整路径名。这将避免搜索路径问题。

      • 默认情况下,“sudo”使用 syslog(3) 记录失败的命令。看看是否可以在相应的日志文件中找到踪迹。

      【讨论】:

        【解决方案4】:

        假设您可以从命令行运行命令,以 tomcat 用户身份登录 - 尝试

        ProcessBuilder pb = new ProcessBuilder("/usr/bin/sudo", "cp", 
                            "/var/tmp/mailserverfiles/editinterface.txt", 
                            "/etc/sysconfig/network-scripts/editinterface.txt");
        pb.redirectErrorStream(true);
        Process proc = pb.start();
        ... rest of code as before
        

        如果仍然失败,请开始调试。 strace 应该会有所帮助。例如运行这个 shell 脚本 从您的 java 应用程序中找出问题所在 /tmp/trace.txt 文件:

        #!/bin/sh
        
        strace -f sudo cp /var/tmp/mailserverfiles/editinterface.txt /etc/sysconfig/network-scripts/editinterface.txt  >/tmp/trace.txt 2>&1
        

        【讨论】:

          【解决方案5】:

          虽然没有直接回答您的问题,但以下内容会有所帮助。您需要读取 stdout 和 stderr(以捕获所有进程输出),并同时执行此操作以防止阻塞生成的进程。请参阅this answer 了解更多信息。

          【讨论】:

            猜你喜欢
            • 2013-10-13
            • 1970-01-01
            • 2019-08-16
            • 1970-01-01
            • 1970-01-01
            • 2012-01-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多