我正在编写一个java程序,它在本地Linux主机上运行rsync以将数据复制到远程主机。我正在使用jsch库。我查看了jsch示例,但我没有发现任何相关内容。
我无法设置密钥身份验证,因此当rsync命令运行提示输入密码时,我希望自动输入远程主机的密码。
我在网上搜索了一些方法,我找不到任何简单的方法。
以下函数只执行输入命令,此函数是具有服务器,用户名,密码的类的一部分
public int executeCommand(String command) throws Exception {
JSch jsch = new JSch();
Session session = null;
Channel channel = null;
int exitCode;
try {
//Initialize session
session = jsch.getSession(this.username, this.server, 22);
session.setPassword(this.password);
session.setConfig("StrictHostKeyChecking", "no");
session.setConfig("PreferredAuthentications", "publickey,password");
//Connect
session.connect();
//Open a channel for communication
channel = session.openChannel("shell");
OutputStream ops = channel.getOutputStream();
PrintStream ps = new PrintStream(ops, true);
channel.connect();
logger.info("Sending command {} ",command);
ps.println(command);
ps.flush();
InputStream inputStream = channel.getInputStream();
processOutput(inputStream, "password:", timeout);
logger.info("Sending password.");
ps.println(this.targetPassword);
ps.flush();
processOutput(inputStream, "total size is", timeout);
//Get the process exit code
String exitCodeCommand = "echo $?";
logger.info("Sending command {} ",exitCodeCommand);
ps.println(exitCodeCommand);
ps.flush();
String exitCodeOutput = processOutput(inputStream, "", 0.5);
String[] outputArray = exitCodeOutput.split(System.lineSeparator());
if (outputArray.length < 2) {
String msg = String.format("Exit code of command $1%s is invalid %2$s", exitCodeCommand,
exitCodeOutput);
throw new Exception(msg);
}
try {
exitCode = Integer.parseInt(outputArray[1]);
} catch (NumberFormatException nfe) {
logger.error("Exception occurred while parsing {}", outputArray[1], nfe);
String msg = String.format("Exit code of command $1%s is invalid %2$s. Exit code parsed %3$s is " +
"not an integer", exitCodeCommand, exitCodeOutput, outputArray[2]);
throw new Exception(msg);
}
logger.info("Exit code {}", exitCode);
inputStream.close();
ps.close();
channel.disconnect();
session.disconnect();
} catch (JSchException e) {
logger.error("Exception occurred while creating session with {}. Error message {}", this.server, e
.getMessage(), e);
} catch (IOException e) {
logger.error("Exception occurred while creating performing IO with server {}. Error message {}", this
.server, e.getMessage(), e);
} finally {
logger.info("Closing channels");
if (channel != null && !channel.isClosed()) {
channel.disconnect();
}
if (session != null) {
session.disconnect();
}
}
return exitCode;
}
private String processOutput(InputStream inputStream, String outToFind, double timeout) throws Exception {
byte[] bt = new byte[1024];
StringBuilder builder = new StringBuilder();
double timeoutBeforeExit = timeout * 1000 * 60;
double timeElapsed = 0;
while (true) {
try {
while (inputStream.available() > 0) {
int i = inputStream.read(bt, 0, 1024);
if (i < 0) {
break;
}
String str = new String(bt, 0, i);
builder.append(str);
//displays the output of the command executed for debug purpose.
logger.info(str);
if (str.contains(outToFind)) {
logger.info("{} output is found.", outToFind);
return builder.toString();
} else {
logger.info("{} is not matched", str);
}
}
} catch (IOException e) {
logger.error("Exception occurred while creating performing IO with server {}. Error message {}", this
.server, e.getMessage(), e);
throw new Exception(e.getMessage());
}
timeElapsed = timeElapsed + SLEEP_TIME;
if (timeElapsed >= timeoutBeforeExit) {
throw new Exception("Timeout while waiting for output.");
}
try {
Thread.sleep(SLEEP_TIME);
} catch (InterruptedException e) {
logger.warn("Benign exception occurred inputStream thread sleep. Continuing.", e);
}
}
}
答案 0 :(得分:0)
您可以尝试以下代码。它会自动读取提供的密码并继续运行下一个命令。
/**
* Transfer a file to remote destination via JSCH library using sFTP protocol
*
* @param username String remote SFTP server user name.
* @param password String remote SFTP server user password
* @param host String remote SFTP server IP address or host name.
* @param file File to transfer to SFTP Server.
* @param transferProtocol protocol to transfer a file. {@link FileTransferProtocol}
* @return boolean true if file is transfered otherwise false.
* @throws ApplicationException
*/
public static boolean transferFile(final String username, final String password, final String host,
final File file, final FileTransferProtocol transferProtocol) {
// throws ApplicationException {
// currently can deal with sftp only.
// LOGGER.trace("Invoking transferFile...");
JSch jsch = new JSch();
try {
Session session = jsch.getSession(username, host);
// LOGGER.debug("Session Host: " + session.getHost());
session.setPassword(password);
Properties properties = new Properties();
properties.put("StrictHostKeyChecking", "no");
session.setConfig(properties);
// LOGGER.debug("Connecting to a session Host Server...");
session.connect();
// LOGGER.debug("session is established with host server.");
// Channel channel = session.openChannel(transferProtocol.ftpStringRepresentation());
Channel channel = session.openChannel("sftp");
// LOGGER.debug("Connecting to a sftp Channel...");
channel.connect();
// LOGGER.debug("Connected with sftp Channel.");
ChannelSftp channelSftp = (ChannelSftp) channel;
channelSftp.put(new FileInputStream(file), file.getName());
// LOGGER.debug("File transfered successfully");
channelSftp.exit();
// LOGGER.debug("sftp channel disconnected.");
channel.disconnect();
// LOGGER.debug("channel disconnected.");
session.disconnect();
// LOGGER.debug("session disconnected.");
return true;
} catch (JSchException | FileNotFoundException | SftpException e) {
e.printStackTrace();
// LOGGER.error(e.getMessage(), e.getCause());
// throw new ApplicationException(e.getMessage(), ApplicationSeverity.ERROR, e.getCause(), e);
}
return false;
}