【问题标题】:ProcessBuilder.start() returns 0 but doesn't execute shell scriptProcessBuilder.start() 返回 0 但不执行 shell 脚本
【发布时间】:2013-04-06 05:08:05
【问题描述】:

我正在尝试使用 ProcessBuilder 从运行在 WebSphere Application Server 上的 Servlet 在我的 Linux 服务器上执行 shell 脚本。

代码返回 0(使用 .waitFor()),但脚本似乎没有执行。 如果我给脚本设置了一个无效路径,我会得到一个“找不到文件”异常,所以我知道它正在查找脚本……但似乎没有执行。

脚本本身调用了另一个脚本,该脚本最终应该输出一个 zip 文件(我还有一个“触摸”行来查看那里是否发生了任何事情……但什么也没做)。

脚本从命令行运行良好,使用的命令与我通过 .start() 传递的命令相同。

这是我的 Servlet 中的一个 sn-p:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    System.out.println("in doPost");


    System.out.println("about to kick off ProcessBuilder");
    ProcessBuilder pb = new ProcessBuilder("/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/installedApps/localhostNode01Cell/Svc_war.ear/Svc.war/test.sh");
    pb.redirectErrorStream(true);
    Process process = pb.start();
    BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
    int ch;
    while ((ch = br.read()) != -1)
        System.out.println((char)ch);
    br.close();
    try {
        int exitVal = process.waitFor();
        System.out.println("Exit Value: " + exitVal);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

.redirectErrorStream() 和 .getInputStream() 用于查看我是否会遇到一些我读过其他人提到的缓冲区问题(尽管我不希望 .waitFor() 如果那是返回 0案例)。

这是我第一次涉足 ProcessBuilder,所以我希望我只是遗漏了一些明显的东西。

任何想法/提示将不胜感激。

哦,是的...这是我得到的输出:

[4/5/13 21:32:41:791 PDT] 0000004d SystemOut     O in doPost
[4/5/13 21:32:41:791 PDT] 0000004d SystemOut     O about to kick off ProcessBuilder
[4/5/13 21:32:41:818 PDT] 0000004d SystemOut     O Exit Value: 0

谢谢。

【问题讨论】:

    标签: shell servlets processbuilder


    【解决方案1】:

    搞定了....我需要使用以下方法设置工作目录:

    pb.directory(new File("/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/installedApps/localhostNode01Cell/Svc_war.ear/Svc.war/"));
    

    所以最终的解决方案如下:

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    System.out.println("in doPost");
    
    
    System.out.println("about to kick off ProcessBuilder");
    ProcessBuilder pb = new ProcessBuilder("/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/installedApps/localhostNode01Cell/Svc_war.ear/Svc.war/test.sh");
    pb.redirectErrorStream(true);
    pb.directory(new File("/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/installedApps/localhostNode01Cell/Svc_war.ear/Svc.war/"));
    Process process = pb.start();
    BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
    int ch;
    while ((ch = br.read()) != -1)
        System.out.println((char)ch);
    br.close();
    try {
        int exitVal = process.waitFor();
        System.out.println("Exit Value: " + exitVal);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    

    【讨论】:

      【解决方案2】:

      您只需将 shell 脚本放在工作目录中。这样做你不需要通过 pb.directory("directory") 来设置 ProcessBuilder 的目录

      【讨论】:

        【解决方案3】:

        脚本从命令行运行良好,使用的命令与我通过 .start() 传递的命令相同。

        我敢打赌,问题是当您从命令行测试它时,您是在一个用户帐户下进行的,而 WebSphere 在另一个帐户下运行它。这两个帐户可能具有不同的访问权限、不同的$PATH 设置等。shell 脚本在一个帐户下工作的事实并不意味着它可以在另一个帐户下工作。你需要测试一下。

        【讨论】:

        • 抱歉...没有提到,我目前在命令行 (root) 测试的同一个帐户下运行 WebSphere。
        猜你喜欢
        • 2021-04-28
        • 1970-01-01
        • 1970-01-01
        • 2021-07-28
        • 1970-01-01
        • 1970-01-01
        • 2013-09-01
        • 2015-12-09
        • 2016-02-21
        相关资源
        最近更新 更多