在 Java 中检测终端命令错误

Detecting terminal command errors in Java

在我的 Java 应用程序中,我使用 exec() 命令调用终端函数:

p = Runtime.getRuntime().exec(command);
p.waitFor();

调用使用 zipunzip 调用。原来我叫:

zip -P password -r encrypted.zip folderIWantToZip

当我通过java调用unzip函数时,我将密码指定为方法参数。如果指定了正确的密码,那么调用应该 unzip 加密文件夹:

unzip -P password encrypted.zip

我想要一种方法来查明输入的密码是否不正确。例如,如果 password 正确,则调用将正确 unzip zip 文件。但我注意到密码不正确不会引发异常。我该如何确定?

您可以读取进程的 ErrorStream 和 InputStream 来确定进程输出。下面给出示例代码

    public static void main(String[] args) {
    try {
        String command = "zip -P password -r encrypted.zip folderIWantToZip";
        Process p = Runtime.getRuntime().exec(command);
        InputStream is = p.getInputStream();
        int waitFor = p.waitFor();
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));


        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println("line:" + line);
        }
        is = p.getErrorStream();
        reader = new BufferedReader(new InputStreamReader(is));
        while ((line = reader.readLine()) != null) {
            System.out.println("ErrorStream:line: " + line);
        }
        System.out.println("waitFor:" + waitFor);
        System.out.println("exitValue:" + p.exitValue());
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

您也可以使用退出代码来验证进程状态,但它特定于程序。通常为零表示成功终止,否则异常终止。

根据我的评论,我要做的第一件事是通过 getInputStream() 和 getErrorStream() 捕获 Process 的 InputStream 和 ErrorStream,但尤其是后者,ErrorStream,如果输入错误。请注意,这些必须在它们自己的线程中完成,否则您将占用您的程序。我通常为此使用某种类型的 StreamGobbler class。另外,不要忽略 p.waitFor().

返回的 int

例如,

  ProcessBuilder pBuilder = new ProcessBuilder(COMMAND);
  Process process = null;
  try {
     process = pBuilder.start();

     new Thread(new StreamGobbler("Input", process.getInputStream())).start();
     new Thread(new StreamGobbler("Error", process.getErrorStream())).start();

     int exitValue = process.waitFor();
     System.out.println("Exit Value: " + exitValue);
     process.destroy();


  } catch (IOException e) {
     e.printStackTrace();
  } catch (InterruptedException e) {
     e.printStackTrace();
  } finally {
     if (process != null) {
        process.destroy();
     }
  }

并且:

class StreamGobbler implements Runnable {
   private String name;
   private Scanner scanner;

   public StreamGobbler(String name, InputStream inputStream) {
      this.name = name;
      scanner = new Scanner(inputStream);
   }

   @Override
   public void run() {
      while (scanner.hasNextLine()) {
         String line = scanner.nextLine();
         System.out.println(name + ": " + line); // or better, log the line
      }
      scanner.close();
   }
}