2013-04-03 64 views
1

我想用java在特定位置运行脚本。运行良好,如果我手动运行该脚本:Runtime.exec没有运行但没有例外

 /export/home/trace.sh param1 param2 param3 param4 

这是我的代码从Java运行脚本:

 try { 

     Runtime runtime = Runtime.getRuntime(); 
     Process proc = null; 
     System.out.println("starting search"); 
     proc = runtime.exec(pathServer + "/trace.sh " + fullDate + " " + fullDateTo + " " + mA.substring(2) + " " + mB.substring(2)); 
     InputStream inputstream   = proc.getInputStream(); 
     InputStreamReader inputstreamreader = new InputStreamReader(inputstream); 
     BufferedReader bufferedreader   = new BufferedReader(inputstreamreader); 
     System.out.println("end search " + System.currentTimeMillis()); 
     } 
    catch (Exception e) 
     { 
     System.out.println(e.toString()); 
     e.printStackTrace(); 
     } 

如果脚本运行时,它会产生“txt.dat”在指定位置。但是没有生成“txt.dat”。我试图找出异常是什么,但没有例外。

我的代码已经正确吗?我如何知道它是否正在处理脚本?我怎样才能捕捉到在这个过程中发生的任何异常?谢谢。


更新2

我添加一些代码来打印getInputStreamgetErrorStream。 对于getInputStream,我什么也没得到,这意味着它是空的。 对于getErrorStream,我得到这个结果

  Host key verification failed 

我仍然不知道这是什么错误表示。

的Java应用程序在服务器B.运行

一般情况下,我想调用(在服务器B)的脚本将ssh到服务器A和运行在服务器A.它会生成文本其他脚本。 DAT,然后SFTP发布到服务器B.当手动运行它,txt.dat成功生成并传送到服务器B.


更新3

感谢所有帮助和建议。事实证明,我的Java应用程序在不同的用户下运行。当我手动运行它时,我使用了另一个用户。所以,我已经将服务器B的主机密钥添加到服务器A.现在它已成功运行。

+1

你能打印pathServer的值吗? –

+1

你检查了在控制台上手动运行的命令吗? ,它工作正常吗? –

+0

@Sudhanshu:pathServer是“/ export/home”。我已经验证过它。 – angel

回答

1

您可以调试或打印Process.getErrorStreamProcess.getInputStream以检查子过程报告的错误。

我的猜测是你需要调用/bin/sh作为主程序并将脚本作为参数传递,但我不确定。我知道你必须在Windows上这样做。

+0

您好Tim,thx的建议。我终于用getErrorStream捕捉异常,并说:“主机密钥验证失败。”你知道这是什么意思吗?我运行的脚本是为生成的文本,然后sftp到其他服务器。它工作正常,如果我手动运行它 – angel

1

Runtime.exec如果您的命令失败,则不会抛出异常。

您使用process.exitValue()得到执行结果。

此外,您还可以从代码中创建的process.getInputStream()中获取脚本输出,但不会从某些原因读取。在脚本中放入一些echo语句进行调试。

2

您可以对代码进行相当多的改进。

  1. 使用ProcessBuilder来创建您的过程,而不是Runtime。它为您提供更多的选择和更大的控制权
  2. 通过你的命令的每个组件作为一个单独的字符串建设者
  3. 完全消耗你的输出和错误流
  4. 等待的过程中实际完成

类似这样的:

try { 
    ProcessBuilder builder = new ProcessBuilder() 
      .command("/export/home/trace.sh", param1, param2, param3, param4); 
    builder.redirectErrorStream(true); 

    System.out.println("starting search"); 
    Process proc = builder.start(); 
    final BufferedReader bufferedreader = new BufferedReader(
      new InputStreamReader(proc.getInputStream())); 
    new Thread() { 
     @Override 
     public void run() { 

      try { 
       String line = null; 
       StringBuffer buffer = new StringBuffer(2048); 
       while ((line = bufferedreader.readLine()) != null) { 
        buffer.append(line); 
       } 
      } catch (final IOException ioe) { 
       ioe.printStackTrace(); 
      } 
      // Do something with process output, if needed 
     } 
    }.start(); 

    proc.waitFor(); 
    System.out.println("end search " + System.currentTimeMillis()); 
} catch (Exception e) { 
    e.printStackTrace(); 
} 
+0

嗨知觉,THX的建议。我尝试运行你的代码,但我得到这个异常'java.io.IOException:无法运行程序“/export/home/trace.sh 20130401 20130402 62813 62815”:错误= 2,没有这样的文件或目录'我不明白为什么它说没有这样的文件或目录,我甚至运行完全相同的命令并成功。 – angel

+0

脚本是否尝试创建/访问临时目录?您的Java程序可能没有足够的权限运行,并且在通过它调用跟踪程序时无法创建相同的目录。 – Perception

+0

不,它不是创建/访问临时目录。但该脚本将ssh到其他服务器。这是相关的吗?为什么当我使用runtime.exec时错误是不同的?当我使用runtime.exec和捕捉异常,它说'主机密钥验证失败' – angel