Java流程流

时间:2013-11-17 17:15:39

标签: java process terminal inputstream

我遇到与某些终端应用程序交互的问题(在我的情况下,它是openSSL)。我有一个命令发送,然后这个应用程序想要密码和回复给定的密码。我的代码不起作用。我的意思是我没有看到它的任何输出。

为了测试我还做了一个简单的应用程序,它等待两个字符串输入并从我的Java代码中运行它。

你有什么建议吗?

ProcessBuilder pb = new ProcessBuilder("openssl.exe");
    Process process = pb.start();

    final InputStream is = process.getInputStream();
    new Thread(new Runnable() {
        public void run() {
            try {
                BufferedReader reader =
                    new BufferedReader(new InputStreamReader(is));
                String line;
                while ((line = reader.readLine()) != null) {
                    System.out.println(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    is.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }).start();


    OutputStream out = process.getOutputStream();
    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out));

    writer.write("genrsa -des3 -out ca.key 512\n");
    writer.write("password\n");
    writer.write("password\n");
    writer.flush();

    writer.close();
    process.waitFor();

1 个答案:

答案 0 :(得分:1)

我认为,OpenSSL的行为并不像您期望的那样。我尝试了以下(在Linux上):

echo $'genrsa -des3 -out xxx.key 512\npassword\npassword\n' \
    | openssl 2>stderr.txt 1>stdout.txt

它提示我在终端上输入两个密码:

Enter pass phrase for xxx.key:
Verifying - Enter pass phrase for xxx.key:

Stdout.txt收到:

OpenSSL> OpenSSL> OpenSSL> OpenSSL> OpenSSL>

Stderr.txt收到:

Generating RSA private key, 512 bit long modulus
..........++++++++++++
...........++++++++++++
e is 65537 (0x10001)
openssl:Error: 'password' is an invalid command.
openssl:Error: 'password' is an invalid command.

这意味着大多数openssls输出都转到stderr。它不会向stdout输出换行符,因此reader.readLine()永远不会得到完整的行。这就是为什么你没有看到任何输出。 (请改用read()。您可能还需要读取stderr以避免阻塞。)

OpenSSL总是尝试从当前终端获取密码而不回显,而不是从stdin获取。在没有特殊选项的stdin上呈现它们会导致解释为命令。有关详细信息和选项,请参阅此讨论:Securely passing password to openssl via stdin