java - 需要将 SSH 命令自动化到路由器

标签 java linux ssh tcl jsch

我需要找到一种方法来自动向我的路由器发送 ssh 命令。我的目标是在我从我的 Java 程序运行脚本时让路由器重新启动。不过我遇到了一些问题。

首先,这是我从路由器的 ssh 获得的输出序列: 首先我做:

ssh root@192.168.100.1

返回:

root@192.168.100.1's password: 

我输入密码“admin”。然后转到此提示:

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

Password is default value, please modify it!
WAP>

现在,我输入“reset”,它会重启路由器。

我已经尝试将 Tcl 与 Expect 结合使用,虽然我可以让它在 Windows 上运行,但它在 Linux 上却无法运行。这是我的 Tcl 脚本代码:

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

每当我尝试执行它时,Tcl8.6 都会运行它并在没有实际执行任何操作的情况下终止。但是,如果我在运行 Tcl8.6 时手动输入所有这些命令,它就可以正常工作

我还尝试过 JSch Java 库。有了它,我可以让 Java 程序连接并输出路由器的 shell,但是我尝试发送的任何命令都不起作用。这是其中的代码:

    ...
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";

但它做同样的事情。任何人都知道我可以做到这一点的任何其他方式吗?

最佳答案

尝试使用 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 看看它是否适合你。

关于java - 需要将 SSH 命令自动化到路由器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38931206/

相关文章:

使用 JNA 调用 Win32 WaitForSingleObject() 时,Java 计时器不运行

java - Spring bean 如何检测它自己是否已包装在 AOP 代理中?

java TCP客户端: howto send data while reading

命令 "who -b"的行为不同

linux - 将文件复制到其他文件时出现错误。 cp : target is not a directory

java - 我怎样才能只订阅最后的数据?

java - Red Hat Linux 中的低 Java 单进程线程限制

linux - 从我的 bash 脚本执行 ssh IPAddressA -l user "ssh -l IPAddressB ls"时遇到问题

vim - cmder 使用 ssh 以替换模式启动 vim

linux - 树莓派不允许 ssh 通过端口路由