简体   繁体   English

Runtime.exec没有运行但没有异常

[英]Runtime.exec not running but no exception

I want to use java to run a script in a certain location. 我想使用Java在特定位置运行脚本。 The script running fine if I run it manually: 如果我手动运行该脚本,它将运行良好:

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

This is my code to run the script from java: 这是我从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();
      }

If the script running, it will generate "txt.dat" in a specified location. 如果脚本运行,它将在指定位置生成“ txt.dat”。 But there's no "txt.dat" generated. 但是没有生成“ txt.dat”。 I'm trying to figure out what the exception is, but no exception catch. 我试图找出异常是什么,但没有异常捕获。

Is my code already correct? 我的代码已经正确了吗? How do I know if it's processing the script or not? 我怎么知道它是否正在处理脚本? And how can I catch any exception happened during the process? 我如何捕获在此过程中发生的任何异常? Thanks. 谢谢。


Update 2 更新2

I add some code to print getInputStream and getErrorStream . 我添加了一些代码来打印getInputStreamgetErrorStream For getInputStream , I got nothing, which means it's null. 对于getInputStream ,我什么也没得到,这意味着它为空。 For getErrorStream , I get this as a result 对于getErrorStream ,我得到这个结果

         Host key verification failed

I still have no idea what this error means. 我仍然不知道这个错误是什么意思。

The java apps is run in server B. Java应用程序在服务器B中运行。

Generally, the script I'm trying to invoke (in server B) will ssh to server A and run other script in server A. It will generate text.dat and then sftp to server B. When run it manually, txt.dat successfully generated and transferred to server B. 通常,我尝试调用的脚本(在服务器B中)将SSH到服务器A并在服务器A中运行其他脚本。它将生成text.dat,然后sftp到服务器B。手动运行时,txt.dat成功生成并传输到服务器B。


Update 3 更新3

Thanks for all help and suggestion. 感谢您的所有帮助和建议。 Turns out, my java apps running under different user. 原来,我的Java应用程序在不同的用户下运行。 When I run it manually, I used another user. 当我手动运行它时,我使用了另一个用户。 So, I have added host key from server B to server A. And it's running successfully now. 因此,我已将主机密钥从服务器B添加到服务器A。它现在已成功运行。

Runtime.exec doesn't throw exception if your command fails. 如果您的命令失败, Runtime.exec不会引发异常。

You get the result of execution using the process.exitValue() . 您可以使用process.exitValue()获得执行结果。

Also you can get your script output reading from the process.getInputStream() which you do create in your code but don't read from for some reason. 您也可以从您在代码中创建的process.getInputStream()读取脚本输出,但由于某些原因而无法读取。 Put some echo statements in your script to debug. 在脚本中放入一些echo语句以进行调试。

There are quite a few improvements that you can make to your code. 您可以对代码进行很多改进。

  1. Use ProcessBuilder to create your process, as opposed to Runtime . 使用ProcessBuilder创建您的流程,而不是Runtime It provides you more options and greater control 它为您提供更多选择和更好的控制
  2. Pass each component of your command as a separate string to the builder 将命令的每个组件作为单独的字符串传递给构建器
  3. Fully consume your output and error streams 完全消耗您的输出和错误流
  4. Wait for the process to actually complete 等待过程实际完成

Something like this: 像这样:

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();
}

You can debug or print the Process.getErrorStream and Process.getInputStream to check for an error reported by the sub-process. 您可以调试或打印Process.getErrorStreamProcess.getInputStream来检查子流程报告的错误。

My guess is that you need to invoke /bin/sh as the main program and pass your script as an argument, but I'm not sure. 我的猜测是您需要调用/bin/sh作为主程序,并将脚本作为参数传递,但是我不确定。 I know that you have to do that on windows. 我知道您必须在Windows上执行此操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM