Необходимо автоматизировать команды SSH для маршрутизатора

Мне нужно найти способ автоматизировать команды ssh для моего маршрутизатора. Моя цель - перезапустить маршрутизатор всякий раз, когда я запускаю скрипт из своей программы на Java. Однако у меня есть некоторые проблемы.

Прежде всего, это последовательность вывода, которую я получаю от ssh моего маршрутизатора: Сначала я делаю:

ssh [email protected]

который возвращает:

[email protected]'s password: 

Ввожу пароль "admin". Затем он переходит к этой подсказке:

Welcome Visiting Huawei Home Gateway
Copyright by Huawei Technologies Co., Ltd.

Password is default value, please modify it!
WAP>

Теперь я ввожу «сброс», и он перезагружает маршрутизатор.

Я пробовал Tcl с Expect, и хотя я могу заставить его работать в Windows, он не работает в Linux. Вот мой код для скрипта Tcl:

#!/bin/sh
# \ exec tclsh "$0" ${1+"$@"}
package require Expect
spawn ssh [email protected]
send "admin\r"
send "reset\r"
after 3000
exit

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

Я также пробовал библиотеку JSch Java. При этом я могу заставить программу Java подключиться и вывести оболочку маршрутизатора, но любая команда, которую я пытаюсь отправить, ничего не делает. Вот код оттуда:

    ...
JSch jsch = new JSch();

        Session session = jsch.getSession("root", "192.168.100.1", 22);

        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);

        // Skip prompting for the password info and go direct...
        session.setPassword("admin");
        session.connect();

        String command = "reset\r";

        Channel channel = session.openChannel("exec");
        ((ChannelExec) channel).setCommand(command);

        ((ChannelExec) channel).setErrStream(System.err);

        InputStream in = channel.getInputStream();

        System.out.println("Connect to session...");
        channel.connect();


        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()) {
                System.out.println("exit-status: " + channel.getExitStatus());
                break;
            }
            try {
                Thread.sleep(1000);
            } catch (Exception ee) {
            }
        }
        channel.disconnect();
        session.disconnect();
        System.out.println("disconnected");

Это вывод, который я получаю:

Connect to session...

Welcome Visiting Huawei Home Gateway
Copyright by Huawei Technologies Co., Ltd.

Password is default value, please modify it!
WAP>

Он просто остается здесь, пока я не выйду. Роутер не перезагружается. Я также пробовал:

String command = "reset";

но он делает то же самое. Кто-нибудь знает какие-либо другие способы, которыми я мог бы это сделать?


person seventy70    schedule 13.08.2016    source источник
comment
Я только что заметил, что ваша команда заканчивается на \r. Вместо этого попробуйте \n и посмотрите, подойдет ли он вам.   -  person vempo    schedule 13.08.2016


Ответы (1)


Попробуйте взаимодействовать с устройством с помощью shell вместо exec.

Вот быстрый и грязный код, который я использовал для этого, вы можете настроить его в соответствии со своими потребностями:

private static final String PROMPT = ">";

public static void main(String[] args) throws Exception {

    Session session = null;
    ChannelShell channel = null;

    try {

        JSch jsch = new JSch();
        session = jsch.getSession("root", "192.168.100.1", 22);
        session.setConfig("StrictHostKeyChecking", "no");
        session.setPassword("admin");
        session.connect();

        channel = (ChannelShell) session.openChannel("shell");

        PipedOutputStream reply = new PipedOutputStream();
        PipedInputStream input = new PipedInputStream(reply);
        ByteArrayOutputStream output = new ByteArrayOutputStream();

        channel.setInputStream(input, true);
        channel.setOutputStream(output, true);

        channel.connect();

        getPrompt(channel, output);
        writeCommand(reply, "reset");
        getPrompt(channel, output);

    } finally {

        if (channel != null) {
            channel.disconnect();
        }

        if (session != null) {
            session.disconnect();
        }
    }
}

private static void writeCommand(PipedOutputStream reply, String command) throws IOException {
    System.out.println("Command: " + command);
    reply.write(command.getBytes());
    reply.write("\n".getBytes());
}

private static void getPrompt(ChannelShell channel, ByteArrayOutputStream output)
        throws UnsupportedEncodingException, InterruptedException {

    while (!channel.isClosed()) {

        String response = new String(output.toByteArray(), "UTF-8");
        System.out.println(response);
        if (response.trim().endsWith(PROMPT)) {
            output.reset();
            return;
        }

        Thread.sleep(100);
    }
}

ОБНОВЛЕНИЕ: я заметил, что команда, которую вы отправляете через SSH, заканчивается на \r. Вместо этого попробуйте \n и посмотрите, подойдет ли он вам.

person vempo    schedule 13.08.2016
comment
К сожалению, похоже, что он тоже не работает с этим кодом. Он просто делает то же самое. Выводит оболочку роутера, но после ничего не делает. Я пробовал и \n, и \r. - person seventy70; 13.08.2016
comment
Кажется, теперь это работает. Ваш код в порядке, просто я внес небольшую модификацию, которая вызывала проблемы. Спасибо! - person seventy70; 13.08.2016
comment
Большой! Вы можете объяснить эту модификацию в обновлении вашего вопроса, чтобы другие знали. Или напишите сюда, и я обновлю ответ. - person vempo; 13.08.2016
comment
О нет, ваш код в порядке. Просто я по какой-то причине пытался избавиться от методов, из-за которых все испортилось. Тем не менее, используя его так, как он есть, он работает нормально. - person seventy70; 14.08.2016