Рубрики
Без рубрики

Java – Запуск сценария командной оболочки на удаленном сервере

В Java мы можем использовать библиотеку `JSch` для запуска сценария оболочки на удаленном сервере через SSH.

Автор оригинала: 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-ввод-вывод

Рекомендации

Оригинал: “https://mkyong.com/java/java-run-shell-script-on-a-remote-server/”