Как мне изменить каталог (cd) с помощью Ganymed SSH API?

#java #session #ssh #cd

#java #сессия #ssh #cd

Вопрос:

Должно быть, я что-то здесь упускаю, но как мне вызвать что-то вроде «cd / root / some / dir /» с помощью Ganymed SSH API?

  1. Я создал Connection объект

  2. В первом созданном сеансе я вызвал «cd / root / some / dir»

  3. Во втором созданном сеансе я вызвал «ls .» или «./ MyApp».

Это не сработало, потому что ganymed, вероятно, запускает каждый сеанс со своего собственного каталога

Так нужно ли мне выполнять обе команды в одном сеансе? что-то вроде:

 session.getStdin().write("cd /root/somedir n".getBytes());
session.getStdin().write("ls . ".getBytes());
  

Это правильный путь?? если да, то зачем нам это нужно Session.execCommand ?

Комментарии:

1. Я никогда не использовал эту конкретную библиотеку, но вы пытались один раз получить стандартный идентификатор, сохранить его в переменной, а затем использовать его?

Ответ №1:

После некоторых исследований единственным хорошим решением, которое мне удалось найти, является вызов команды «cd» в том же коде, что и команда «ls», например

 session.execCommand("cd /root/somedir ; ls .");
  

Точка с запятой будет разделять две команды, как и в любом коде bash.

Таким образом, вы можете запросить результат сеанса [ session.getExitStatus() ] обеих команд cd and ls , что намного лучше, чем запись двух команд to session.getStdIn() (после записи в stdin вы как бы теряете возможность проверять статус выхода …)

Надеюсь, это поможет остальным

Эял

Ответ №2:

Согласно часто задаваемым вопросам Ganymed (http://www.ganymed.ethz.ch/ssh2/FAQ.html ), вам не разрешается отправлять более одной команды на каждый объект сеанса, который вы создаете. По-видимому, SSH-2 хочет, чтобы вы с этим справились. Ваши два варианта — либо объединить две команды, например

 session.execCommand("cd /root/somedir ; ls .");
  

Однако это не всегда работает, и это становится очень некрасивым, если у вас больше пары команд. Другой способ сделать это — открыть сеанс интерактивной оболочки и записать команды в стандартный. Это может выглядеть примерно так:

 Session sess = conn.openSession();
sess.requestDumbPTY();
sess.startShell();

OutputStream os = sess.getStdin();
os.write("cd /root/somedirn".getBytes());
os.write("ls -1n".getBytes());
os.write("exitn".getBytes());

InputStream stdout = new StreamGobbler(sess.getStdout());
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));

//TODO
  

Обратите внимание на использование последней команды exit . Поскольку это обрабатывается как окно терминала, если вы не выйдете из программы, любой цикл, который вы читаете, вывод сервера никогда не завершится, потому что сервер будет ожидать большего ввода

Комментарии:

1. Спасибо за этот код! Помогло решить то, над чем я некоторое время был в тупике

Ответ №3:

Хорошо, я быстро взглянул на Ganymed javadoc, и хотя я сам не пробовал, я предполагаю, что вы должны использовать метод execCommand() сеанса вместо записи в стандартный интерфейс. Я почти уверен, что сеанс подключен к удаленной оболочке и, следовательно, обрабатывает состояние оболочки, включая текущий каталог, переменные среды и т.д.

Итак, просто выполните следующие действия:

 session.execCommand("cd /root/somedir n".getBytes());
session.execCommand("ls . ".getBytes());
  

Я надеюсь, что это сработает для вас. Удачи.

Комментарии:

1. Алекс, боюсь, что для этого вопроса нет готового решения api… Я просматривал API взад и вперед в течение нескольких недель… предложенный вами код даже не будет компилироваться, и после его исправления произойдет сбой основных концепций Ganymed SSH