#java #ssh #jsch
#java #ssh #jsch
Вопрос:
Я использую java ssh tools, чтобы установить ssh-соединение со своей школьной учетной записью и выполнить поиск файла, а затем удалить его. Однако я создаю три функции для выполнения одного и того же действия, но с разными файлами, я ищу способ сделать это одновременно, вместо того чтобы выполнять одно за другим. Вот некоторый код. В принципе, я хочу знать, есть ли способ сделать все это через одно ssh-соединение или какой-то форк или многопоточность.
public void updateinterval() {
try {
JSch jsch = new JSch();
String user = "***********";
String host = "********";
Session session = jsch.getSession(user, host, 22);
session.setPassword("*********");
// username and password will be given via UserInfo interface.
UserInfo userInfo = new SftpUserInfo();
session.setUserInfo(userInfo);
session.connect();
// look for a file named feedinterval
String checkfortimeupdate =
"cd public_html/final;grep '-send' feedinterval";
Channel channel = session.openChannel("exec");
((ChannelExec) channel).setCommand(checkfortimeupdate);
// X Forwarding
// channel.setXForwarding(true);
// channel.setInputStream(System.in);
channel.setInputStream(null);
// channel.setOutputStream(System.out);
// FileOutputStream fos=new FileOutputStream("/tmp/stderr");
// ((ChannelExec)channel).setErrStream(fos);
((ChannelExec) channel).setErrStream(System.err);
InputStream in = channel.getInputStream();
channel.connect();
byte[] tmp = new byte[1024];
while (true) {
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0)
break;
String returned = new String(tmp, 0, i);
String argument = returned.substring(6);
if (returned.contains("-send")) {
// if its there its calls the removeinterval function
// which removes the file it found
// by doing the same thing this function does but with a
// different ssh command
arduinoupdate hey = new arduinoupdate();
hey.removeinterval();
try {
Runtime rt = Runtime.getRuntime();
String[] commands = {
"system.exe", "-send", argument };
Process proc = rt.exec(commands);
}
catch (IOException e) {
}
}
}
if (channel.isClosed()) {
System.out.println("UpdateInterval Closed exit-status: "
channel.getExitStatus());
break;
}
try {
/* Thread.sleep(1000); */
} catch (Exception ee) {
}
}
channel.disconnect();
session.disconnect();
} catch (Exception e) {
System.out.println(e);
}
}
Комментарии:
1. пожалуйста, уделите хотя бы несколько минут правильному форматированию вашего кода. Используйте
{}
кнопку в редакторе и убедитесь, что ваш код доступен для чтения при предварительном просмотре.2. Можете ли вы отформатировать свой код или удалить ненужные фрагменты?
3. Кроме того, я бы рекомендовал разложить эту функцию на небольшие методы из 1-4 строк для удобства чтения.
Ответ №1:
Если вы хотите выполнить несколько задач, возможно, ExpectJ будет работать для вас лучше. ExpectJ использует JSCH под прикрытием, так что это может облегчить вам жизнь.
final ExpectJ expectJ = new ExpectJ();
final Spawn spawn = expectJ.spawn("host", 22, "user", "pass");
spawn.send("cd public_html/finaln");
spawn.expect("someReturn");
...
spawn.send("exitn");
spawn.expectClose();
Ответ №2:
Как сказали комментаторы, лучше разложить это по отдельным функциям. Тогда становится более понятным, как повторно использовать одно и то же соединение (т.Е. сеанс) для нескольких команд.
public void updateInterval(Session s, String filename) {
String checkfortimeupdate = "fgrep '-send' "public_html/final/" filename """;
ChannelExec channel = (ChannelExec)session.openChannel("exec");
channel.setCommand(checkfortimeupdate);
channel.setInputStream(null);
channel.setErrStream(System.err);
BufferedReader in = new BufferedReader(new InputStreamReader(channel.getInputStream(), encoding));
channel.connect();
eatOutput(in);
if (channel.isClosed()) {
System.out.println("UpdateInterval Closed exit-status: "
channel.getExitStatus());
break;
}
channel.disconnect();
}
Затем поместите чтение из BufferedReader (у него есть readLine
метод) в метод eatOutput
и используйте другой метод, который открывает сеанс и трижды вызывает метод, показанный здесь (с разными именами файлов), и снова закрывает сеанс.
Ответ №3:
Что касается использования ExpectJ, какая библиотека лучше всего подходит для использования в критически важных производственных приложениях для обеспечения ожидаемой функциональности?
Библиотека ExpectJ или Expect4J? Тем не менее, обе библиотеки используют JSch внизу! Или Apache SSHD — клиент:
SshClient client = SshClient.setUpDefaultClient(); PipedOutputStream PipedIn...?