【问题标题】:How do you run an external command from a Java servlet?如何从 Java servlet 运行外部命令?
【发布时间】:2012-01-05 00:57:35
【问题描述】:

我正在开发一个小型 Web 应用程序,它请求用户输入并将该输入作为服务器端机器上外部程序的命令行参数传递。

public class WorkflowServlet extends HttpServlet 

  public void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
    String username = request.getParameter( "username" );
    String workflow = request.getParameter( "workflow" );
    String preInflation = request.getParamater( "preInflation" );
    String email = request.getParamater( "email" );

    try {
      executeShellCommand( "java ClusterProcess " + username + " "
                            + workflow + " " + preInflation + " " + email );
    } catch ( Exception e ) {
      response.sendRedirect( "WorkflowAction.jsp" ); return;
    }

      response.sendRedirect( "WorkflowInProgress.jsp" );
    }
  }


  public static void executeShellCommand( String command ) {
      Runtime.getRuntime().exec( command.split( " " ) ).waitFor();
  }
}

没有抛出异常 - 它似乎什么都不做。即使我传递了一些非常简单的东西,例如“touch test.txt”来执行ShellCommmand,它什么也不做。我可以通过命令行手动成功运行命令。

我必须做什么?

【问题讨论】:

  • 另外,你为什么不使用waitFor的返回值呢?它可能会告诉你一些事情。
  • 你能发布运行它的 URL 吗? (不,真的,不要 - 你没有逃避你的用户输入!!)
  • @Garee -- 使用 ProcessBuilder。它节省了空格处理的麻烦..命令可能在不同的工作目录(网络服务器的工作目录)中执行..尝试类似 /bin/touch /tmp/atestfile.txt
  • @davogotland,拆分将输入分成单独的参数。否则,在移交给操作系统时,它将被视为单个参数。

标签: java servlets runtime.exec


【解决方案1】:

如果不捕获输入流或错误流,您就会错过流程中的潜在反馈。我根据我之前编写的内容改编了以下代码(在我的 IDE 之外),所以如果有明显的错误,我深表歉意。

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
...

String[] commands = {"/usr/bin/touch", "/home/blah/test.txt"};
//this could be set to a specific directory, if desired
File dir = null;
BufferedReader is = null;
BufferedReader es = null;

try
{
    Process process;
    if (dir != null)
        process = Runtime.getRuntime().exec(commands, null, directory);
    else
        process = Runtime.getRuntime().exec(commands);
    String line;
    is = new BufferedReader(new InputStreamReader(process.getInputStream()));
    while((line = is.readLine()) != null)
        System.out.println(line);
    es = new BufferedReader(new InputStreamReader(process.getErrorStream()));
    while((line = es.readLine()) != null)
        System.err.println(line);

    int exitCode = process.waitFor();
    if (exitCode == 0)
        System.out.println("It worked");
    else
        System.out.println("Something bad happend. Exit code: " + exitCode);
} //try
catch(Exception e)
{
    System.out.println("Something when wrong: " + e.getMessage());
    e.printStackTrace();
} //catch
finally
{
    if (is != null)
        try { is.close(); } catch (IOException e) {}
    if (os != null)
        try { es.close(); } catch (IOException e) {}
} //finally

【讨论】:

  • 您的代码不能解决这个问题。 servlet 未正确重定向。
  • @artaxerxe - 我不确定你的意思。原始帖子中没有关于重定向的内容。另外,我提供的代码示例是为了演示读取输入流和错误流。它不打算成为一个 servlet 示例。
【解决方案2】:

你混淆了exec()ing 的东西,并使用了一个包含各种漂亮东西的 shell ......比如搜索路径。

指定你要exec()的进程的完整路径;例如/usr/bin/touch/path/to/java

【讨论】:

    猜你喜欢
    • 2011-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-18
    • 2012-11-04
    • 1970-01-01
    • 2011-02-02
    • 1970-01-01
    相关资源
    最近更新 更多