Автор оригинала: mkyong.
В этой статье показано, как использовать JSch библиотека для запуска или выполнения сценария оболочки на удаленном сервере через SSH.
com.jcraft jsch 0.1.55
1. Запустите сценарий удаленной оболочки
Этот пример Java использует JSch для входа по SSH на удаленный сервер (с использованием пароля) и запускает сценарий оболочки hello.sh
.
1.1 Вот простой сценарий оболочки на удаленном сервере, IP-адрес 1.1.1.1
.
#! /bin/sh echo "hello $1\n";
Назначено разрешение на выполнение.
$ chmod +x hello.sh
1.2 В локальном режиме мы можем использовать приведенный ниже код для запуска или выполнения описанного выше сценария оболочки на удаленном сервере.
package com.mkyong.io.howto; import com.jcraft.jsch.*; import java.io.IOException; import java.io.InputStream; public class RunRemoteScript { private static final String REMOTE_HOST = "1.1.1.1"; private static final String USERNAME = ""; private static final String PASSWORD = ""; private static final int REMOTE_PORT = 22; private static final int SESSION_TIMEOUT = 10000; private static final int CHANNEL_TIMEOUT = 5000; public static void main(String[] args) { String remoteShellScript = "/root/hello.sh"; Session jschSession = null; try { JSch jsch = new JSch(); jsch.setKnownHosts("/home/mkyong/.ssh/known_hosts"); jschSession = jsch.getSession(USERNAME, REMOTE_HOST, REMOTE_PORT); // not recommend, uses jsch.setKnownHosts //jschSession.setConfig("StrictHostKeyChecking", "no"); // authenticate using password jschSession.setPassword(PASSWORD); // 10 seconds timeout session jschSession.connect(SESSION_TIMEOUT); ChannelExec channelExec = (ChannelExec) jschSession.openChannel("exec"); // run a shell script channelExec.setCommand("sh " + remoteShellScript + " mkyong"); // display errors to System.err channelExec.setErrStream(System.err); InputStream in = channelExec.getInputStream(); // 5 seconds timeout channel channelExec.connect(CHANNEL_TIMEOUT); // read the result from remote server 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 (channelExec.isClosed()) { if (in.available() > 0) continue; System.out.println("exit-status: " + channelExec.getExitStatus()); break; } try { Thread.sleep(1000); } catch (Exception ee) { } } channelExec.disconnect(); } catch (JSchException | IOException e) { e.printStackTrace(); } finally { if (jschSession != null) { jschSession.disconnect(); } } } }
Выход
hello mkyong exit-status: 0
Примечание Для JSch Неизвестный ключ хоста
исключение, пожалуйста, добавьте IP-адрес удаленного сервера в .ssh/known_hosts
, прочитайте это .
2. Выполнить Удаленную Команду
2.1 Приведенный ниже пример очень похож на приведенный выше пример №1. Вместо этого он использует закрытый ключ id_rsa
для входа по SSH на удаленный сервер убедитесь, что удаленный сервер правильно настроил открытый ключ .
jsch.addIdentity("/home/mkyong/.ssh/id_rsa");
2.2 И мы изменили команду на ls
, остальные коды те же самые.
channelExec.setCommand("ls -lsah");
2.3 В этом примере Java выполняется команда удаленного сервера ls -lsah
для отображения списка каталогов.
package com.mkyong.io.howto; import com.jcraft.jsch.*; import java.io.IOException; import java.io.InputStream; public class RunRemoteCommand { private static final String REMOTE_HOST = "1.1.1.1"; private static final String USERNAME = ""; private static final int REMOTE_PORT = 22; private static final int SESSION_TIMEOUT = 10000; private static final int CHANNEL_TIMEOUT = 5000; public static void main(String[] args) { Session jschSession = null; try { JSch jsch = new JSch(); jsch.setKnownHosts("/home/mkyong/.ssh/known_hosts"); jschSession = jsch.getSession(USERNAME, REMOTE_HOST, REMOTE_PORT); // not recommend, uses jsch.setKnownHosts //jschSession.setConfig("StrictHostKeyChecking", "no"); // authenticate using private key jsch.addIdentity("/home/mkyong/.ssh/id_rsa"); // 10 seconds timeout session jschSession.connect(SESSION_TIMEOUT); ChannelExec channelExec = (ChannelExec) jschSession.openChannel("exec"); // Run a command channelExec.setCommand("ls -lsah"); // display errors to System.err channelExec.setErrStream(System.err); InputStream in = channelExec.getInputStream(); // 5 seconds timeout channel channelExec.connect(CHANNEL_TIMEOUT); // read the result from remote server 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 (channelExec.isClosed()) { if (in.available() > 0) continue; System.out.println("exit-status: " + channelExec.getExitStatus()); break; } try { Thread.sleep(1000); } catch (Exception ee) { } } channelExec.disconnect(); } catch (JSchException | IOException e) { e.printStackTrace(); } finally { if (jschSession != null) { jschSession.disconnect(); } } } }
Выход
otal 48K 4.0K drwx------ 6 root root 4.0K Aug 4 07:57 . 4.0K drwxr-xr-x 22 root root 4.0K Sep 11 2019 .. 8.0K -rw------- 1 root root 5.5K Aug 3 08:50 .bash_history 4.0K -rw-r--r-- 1 root root 570 Jan 31 2010 .bashrc 4.0K drwx------ 2 root root 4.0K Dec 15 2019 .cache 4.0K drwx------ 2 root root 4.0K Dec 15 2019 .docker 4.0K -rwxr-xr-x 1 root root 31 Aug 4 07:54 hello.sh 4.0K -rw-r--r-- 1 root root 148 Aug 17 2015 .profile 4.0K drwx------ 2 root root 4.0K Aug 3 05:32 .ssh 4.0K drwxr-xr-x 2 root root 4.0K Aug 3 04:42 test 4.0K -rw------- 1 root root 1.2K Aug 4 07:57 .viminfo exit-status: 0
2.4 Теперь мы проверяем недопустимую команду abc
// Run a invalid command channelExec.setCommand("abc");
Выход
bash: abc: command not found exit-status: 127
Ошибки будут выведены в System.err
.
Скачать Исходный Код
$ клон git $ клон git
$ cd java-ввод-вывод
Рекомендации
- Учебные пособия по написанию сценариев оболочки
- Примеры JSch – Exec.java
- Официальный сайт JSch
- JSch – недопустимое исключение приватного ключа
- JSch – Исключение неизвестного хосткея
Оригинал: “https://mkyong.com/java/java-run-shell-script-on-a-remote-server/”