【发布时间】:2011-09-17 17:35:31
【问题描述】:
我有 rsync 命令要在 java 程序中运行...我面临的问题是 rsync 需要输入密码,我不明白如何将此密码传递给 rsync 命令才能工作?
【问题讨论】:
-
你不能在服务器之间设置无密码 ssh 吗?
标签: java runtime.exec
我有 rsync 命令要在 java 程序中运行...我面临的问题是 rsync 需要输入密码,我不明白如何将此密码传递给 rsync 命令才能工作?
【问题讨论】:
标签: java runtime.exec
我将发布此代码示例:
Process rsyncProc = Runtime.exec ("rsync");
OutputStreanm rsyncStdIn = rsyncProv.getOutputStream ();
rsyncStdIn.write ("password".getBytes ());
但是Vineet Reynolds在我前面。
正如 Vineet Reynolds 指出的那样,使用这种方法将需要一段额外的代码来检测 rsync 何时需要密码。所以使用外部密码文件似乎是一种更简单的方法。
P.S.:可能存在与编码有关的问题,可以通过使用适当的编码将字符串转换为字节数组来解决,如here所述。
P.P.S.:我似乎还不能评论答案,所以我不得不发布一个新答案。
【讨论】:
花了我一些时间,但它是这样的:
Process ssh = Runtime.getRuntime ().exec (new String[] {"rsync", ... /*other arguments*/});
Reader stdOut = new InputStreamReader (ssh.getInputStream (), "US-ASCII");
OutputStream stdIn = ssh.getOutputStream ();
char[] passRequest = new char[128];//Choose it big enough for rsync password request and all that goes before it
int len = 0;
while (true)
{
len += stdOut.read (passRequest, len, passRequest.length - len);
if (new String (passRequest, 0, len).contains ("password:")) break;
}
System.out.println ("Password requested");
stdIn.write ("your_password\n".getBytes ("US-ASCII"));
stdIn.flush ();
P.S.:我真的不知道 rsync 是如何工作的,因此您可能需要对其进行一些更改 - 只需从终端手动运行 rsync 并查看它是如何请求密码的。
【讨论】:
您可以写入Process 的输出流,以传入任何输入。但是,这需要您了解rsync 的行为,因为您必须仅在检测到密码提示时(通过读取Process 的输入流)将密码写入输出流。
但是,您可以创建一个非世界可读的密码文件,并在从 Java 启动 rsync 进程时使用 --password-file 选项传递此密码文件的位置。
【讨论】:
不需要等到密码被请求才将其写入流。改用 BufferedWriter。
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(process.getOutputStream())
);
writer.write(passwd, 0, passwd.length());
writer.newLine();
writer.close();
这必须有效。
【讨论】: