需要将 SSH 命令自动化到路由器
Need to automate SSH commands to router
我需要找到一种方法来自动向我的路由器发送 ssh 命令。我的目标是每当我 运行 来自我的 Java 程序的脚本时让路由器重新启动。不过我遇到了一些问题。
首先,这是我从路由器的 ssh 获得的输出序列:
首先我做:
ssh root@192.168.100.1
哪个returns:
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",它会重启路由器。
我已经用 Expect 尝试了 Tcl,虽然我可以让它在 Windows 上运行,但它在 Linux 上不起作用。这是我的 Tcl 脚本代码:
#!/bin/sh
# \ exec tclsh "[=13=]" ${1+"$@"}
package require Expect
spawn ssh root@192.168.100.1
send "admin\r"
send "reset\r"
after 3000
exit
每当我尝试执行它时,Tcl8.6 运行 都会通过它并终止而实际上没有做任何事情。但是,如果我在 运行ning 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
,看看它是否适合你。
我需要找到一种方法来自动向我的路由器发送 ssh 命令。我的目标是每当我 运行 来自我的 Java 程序的脚本时让路由器重新启动。不过我遇到了一些问题。
首先,这是我从路由器的 ssh 获得的输出序列: 首先我做:
ssh root@192.168.100.1
哪个returns:
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",它会重启路由器。
我已经用 Expect 尝试了 Tcl,虽然我可以让它在 Windows 上运行,但它在 Linux 上不起作用。这是我的 Tcl 脚本代码:
#!/bin/sh
# \ exec tclsh "[=13=]" ${1+"$@"}
package require Expect
spawn ssh root@192.168.100.1
send "admin\r"
send "reset\r"
after 3000
exit
每当我尝试执行它时,Tcl8.6 运行 都会通过它并终止而实际上没有做任何事情。但是,如果我在 运行ning 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
,看看它是否适合你。