我正在尝试在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可能会提示类似"主机‘SOME host’的真实性无法建立…"的信息,这会提示是/否。或者其他我现在无法想象的事情。
我的代码的问题是,它从不读取一行,尽管scp会提示输入密码,这可以在cli中看到。有什么建议吗?
EDIT:正如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的输入流。这也不起作用!我的意思是,当我在命令行中执行jar文件时,我会看到提示"username@host的密码:",它等待密码。当我在没有输入密码的情况下点击回车时,它只是重新询问密码,没有任何错误消息,这意味着Process
的输入流没有字符串,即我的BufferedWriter
似乎什么都没做。
我正在用jdk 1.7.0_45在w8机器上编译我的程序,在那里我用jre 1.7.0_51在Ubuntu Server x64上运行程序。
我发现配置rsa文件和使用scp命令中的-I选项更容易。
只需使用-i,其中是HOST机器的私钥。您还需要将运行该命令的计算机的公钥添加到HOST计算机中的授权密钥文件中。
这样他就不会提示你输入密码了。此外,如果你使用-q-o StrictHostKeyChecking=no-o UserKnownHostsFile=/dev/null选项,你几乎不会有什么担心的(这并不总是一件好事!)