2013-05-02 3 views
2

Я пытаюсь подключиться к хосту, а затем изменить пользователя с помощью «su-john», а затем выполнить команду как john. Можно ли использовать только JSch?Java JSch меняет пользователя на удаленном компьютере и выполняет команду

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

Это, как я подключиться к удаленной машине:

String address = "myremote.computer.com"; 

JSch jsch = new JSch(); 
String user = "tom"; 
String host = address; 
String password = "l33tpaSSw0rd"; 
Session session = jsch.getSession(user, host, 22); 
java.util.Properties config = new java.util.Properties(); 
config.put("StrictHostKeyChecking", "no"); 
session.setConfig(config); 
session.setPassword(password); 

session.connect(); 

Затем я выполнять команды с помощью runSshCommand() метода, который выглядит следующим образом:

try 
{ 
    Channel channel = session.openChannel("exec"); 
    channel.setInputStream(null); 
    channel.setOutputStream(System.out); 

    ((ChannelExec) channel).setCommand(command); 

    channel.connect(); 

    InputStream in = channel.getInputStream(); 

    byte[] tmp = new byte[1024]; 
    while (true) 
    { 
     while (in.available() > 0) 
     { 
      int i = in.read(tmp, 0, 1024); 
      if (i < 0) 
      { 
       break; 
      } 
      System.out.print(new String(tmp, 0, i)); 
     } 
     if (channel.isClosed()) 
     { 
      break; 
     } 
     try 
     { 
      Thread.sleep(1000); 
     } 
     catch (Exception ee) 
     { 
     } 
    } 
    channel.disconnect(); 
} 
catch (Exception e) 
{ 
    e.printStackTrace(); 
} 

Должен ли я создать еще один канал, когда я изменить пользователей или как это сделать?

Потому что, если я использую

runSshCommand("su - john",session); 
runSshCommand("tail -1 ~/mylog.log",session); 

он просто выполняет команду «су», но он не кончает изменение пользователей и после выполнения «хвост» приведет к ошибке, потому что «Томь» hasn» t получил файл:/

В принципе, я хотел бы, чтобы мое приложение подключалось к машине, меняло пользователя, читало один файл и возвращало данные. Может ли кто-нибудь пролить свет, пожалуйста?

ответ

6

У вас есть несколько проблем.

Во-первых, каждый канал в SSH-соединении не зависит от других, а команда в каждом канале exec выполняется в собственной оболочке (интерпретатор командной строки). Таким образом, любые изменения, которые вы делаете в одном канале, не влияют на другие каналы. Вы также не можете делать вещи, как это:

runSshCommand("cd Documents", session); 
runSshCommand("ls -l", session); 

(На самом деле вы можете сделать это, но он не будет отображаться содержимое каталога Documents, но в домашней директории.)

Для cd, вы можете работать вокруг, передавая обе команды, как «команда» один, который будет использоваться в том же канале exec:

runSshCommand("cd Documents; ls -l"); 

(Вместо ; вы также можете использовать разрыв строки \n в SEP arate команды или что-то еще, что принимает ваша оболочка.)

Для su это не сработает, когда мы перейдем на вторую проблему .

su не является командой, которая изменяет состояние текущей оболочки (например, cd), но представляет собой команду, которая открывает новую оболочку внутри существующей. Он вернется только к внешней оболочке, когда вы покинете оболочку, начатую su (например, exit, logout или конец файла), а затем вы снова являетесь тем же пользователем, что и раньше.

Чтобы передать команды в «внутреннюю оболочку», вам необходимо передать их на вход оболочки.Или используйте -c (--command) аргумент su:

runSshCommand("su -c 'tail -1 ~/mylog.log' - john ",session); 

Затем можно запустить в третьей задаче: su запросит пароль Джонса, и может отказаться читать его из стандартного ввода, но попытаться прочитайте его с терминала. И ваш канал не имеет псевдотерминала. Вы можете попробовать использовать cannel.setPty(true), а затем написать пароль в выходной поток, хотя я не уверен, что это сработает.

Альтернатива: Вместо su -c вы можете использовать sudo, который может быть сконфигурирован, чтобы не запрашивать пароль для некоторых команд и пользователей (в противном случае вы будете иметь терминальную проблему снова). Или вы можете войти в систему как john или сделать файл журнала доступным для tom. (Кроме того, я надеюсь, что ваш реальный пароль лучше, чем тот, который находится в вашем исходном коде.)

Смежные вопросы