使用Runtime.exec处理i / o流

时间:2014-01-16 10:32:29

标签: java process stream

我正在尝试在Java中运行scp命令。这是我的代码,

try {
    Process p = Runtime.getRuntime().exec("scp -P" + PORT + " " + FILEPATH + " " + USERNAME + "@" + HOST + ":somefolder/");
    BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
    String line;
    while ((line=br.readLine()) != null) {
        System.out.println("LINE: " + line);
        if (line.contains(USERNAME+"@"+HOST+"'s password:")) {
            bw.write(PASSWORD);
            bw.newLine();
        }
    }
    System.out.println("end of while.");
} catch (IOException e) {
    e.printStackTrace();
}

正如您所看到的,我不想盲目地将密码打印到p.getOutputStream(),这在几乎所有类似的问题中都有建议。我想阅读提示并采取相应行动。例如,scp可能会提示诸如“主机的真实性'某些主机'无法建立......”,这会提示是/否。或者其他我现在无法想象的东西。

我的代码的问题在于它永远不会读取一行,尽管scp会提示输入密码,这可以在cli上看到。有什么建议吗?

修改 正如Andrew Thompson建议的那样,我将代码改为使用ProcessBuilder和String []构造函数。这是完整的代码:

package scptest;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class STest {

    // args => filepath, username, host, port, password
    public static void main(String[] args) {
        try {
            ProcessBuilder pb = new ProcessBuilder("scp", "-P", args[3],
                    args[0], args[1] + "@" + args[2] + ":folder/");
            Process p = pb.start();
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    p.getInputStream()));
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
                    p.getOutputStream()));
            String line;
            bw.write(args[4]);
            bw.newLine();
            bw.flush();
            System.out.println("RETURN: " + p.waitFor());
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

}

如您所见,我退出检查scp的提示,并将密码直接发送到Process的输入流。这也不起作用!我的意思是,当我在commad行中执行jar文件时,我看到提示“username @ host的密码:”,它等待密码。当我在没有输入密码的情况下点击输入时,它只是重新询问密码而没有任何错误消息,这意味着没有给Process的输入流提供字符串,即我的BufferedWriter似乎什么都不做。

我正在使用jdk 1.7.0_45在w8机器上编译我的程序,我在jbu 1.7.0_51的Ubuntu Server x64上运行该程序。

1 个答案:

答案 0 :(得分:0)

我发现更容易配置rsa文件并在scp命令中使用-i选项。

只需使用-i where HOST机器的私钥即可。您还需要将运行该命令的计算机上的公钥添加到HOST计算机中的授权密钥文件中。

这样他就不会提示你输入密码了。此外,如果您使用-q -o StrictHostKeyChecking = no -o UserKnownHostsFile = / dev / null选项,您很少会担心(这并不总是一件好事!)