从Java执行命令

从Java执行命令,java,Java,我正在尝试从Java程序执行一个脚本: public class TestCommandLine { public static void main (String[] args) { String PATH = "/path/programs/"; String command = PATH + "name_programs param1 param2"; executeCommand (command); }

我正在尝试从Java程序执行一个脚本:

public class TestCommandLine 
{
    public static void main (String[] args) 
    {
        String PATH = "/path/programs/";
        String command = PATH + "name_programs param1 param2";
        executeCommand (command);
    }

    private static String executeCommand (String command) 
    {
        StringBuffer output = new StringBuffer();
        String line = "";
        Process p;

        try {
            p = Runtime.getRuntime ().exec (command);
            p.waitFor ();
            BufferedReader reader = new BufferedReader (new InputStreamReader (p.getInputStream ()));


            while ((line = reader.readLine ()) != null) {
                output.append (line + "\n");
            }

        } 
        catch (Exception e) {
            e.printStackTrace ();
        }

        return output.toString ();
    }
}

没有错误,但程序不运行。我还尝试了stackoverflow的其他解决方案,但所有解决方案都不起作用

我唯一一次这样做的时候,我使用了如下方法:

Process p = Runtime.getRuntime().exec("foo.exe");

你试过了吗?如果是,返回的错误是什么?

您的命令正在生成您想要读取的输出,但在命令完成所有输出并退出之前,您拒绝读取任何输出(直到
waitFor()
之后才调用
getInputStream()

如果您的命令没有产生太多输出,这是可以的,Java可以缓冲它。但是,如果您的命令产生大量输出,Java就无法缓冲所有输出,命令就会被阻塞

操作系统不会让命令写入更多输出,因为Java的缓冲区已满,并且您没有指示Java清空它。因此,程序被阻止,Java的
waitFor()
将永远不会回来

为了解决您的问题,您应该在从
exec()
获取
进程
对象后立即调用
getInputStream()
,并且您应该创建一个新的
线程
,负责将命令输出读入
StringBuffer


然后,您应该
waitFor()
进程完成,查看它是否成功退出,然后您可以等待线程到达inputstream的末尾并完成-此时,使用命令的完整输出读取
StringBuffer
是安全的。

如果您从实际命令开始,这会更快

不能使用
Process.exec
运行shell解释的命令。相反,它直接执行程序。因此,输入/输出重定向(
|
等)是不可能的。 如果您实际读取了stderr(
getErrorStream()
)输出,则可能会出现“invalid argument:>”这样的情况

您必须:

  • 用Java重定向输出。从进程的stdout(
    getInputStream()
    )读取并写入某种类型的FileOutputStream
  • 执行shell而不是直接执行命令。例如
    /bin/sh-c“command arg>文件”
    。引用的部分必须作为单个参数传递给
    sh
    。在这种情况下,您将无法在标准输出中看到任何内容,必须打开并读取刚刚写入的文件。第一种选择可能更明智

正如其他地方所指出的,除非您期望的输出量非常小,否则在使用流之前不应等待命令退出。

从一些用于调试的语句开始(或使用适当的调试器逐步执行)。首先打印出命令字符串。如果复制粘贴字符串,它是否在cmd行中手动工作?您还调用了
executeCommand
,但没有捕获返回字符串。那根弦是由什么组成的?你如何确定程序没有运行?预期的行为是什么?已完成。我已经在控制台中打印出我的命令,复制它并粘贴到命令正确工作的命令行中。检查exitValue和getErrorStream()的内容。这就是指出错误的地方。我添加了这个:System.out.println(“Exit:+p.exitValue());退出值为1。getErrorStream()是“Error:java.lang.UNIXProcess$ProcessPipeInputStream@7559f3f0". 事实上,我是这样使用命令的:“path/program/nameProgram input>output”如果重定向输出,您希望如何在
读取器中接收任何输出?“executeCommand(String命令)”方法包含您编写的函数。我也不例外。我没有错