如何用Java在Linux下依次执行telnet与msh等Shell命令
解决Java中执行telnet后无法运行msh命令的问题
我看你现在的Java代码只能跑通telnet,没法执行后续的msh命令,问题其实出在命令的构造方式上,咱们一步步捋清楚:
问题根源
你当前的ProcessBuilder命令列表是这么写的:
List<String> commands = new ArrayList<String>(); commands.add("/bin/bash"); commands.add("-c"); commands.add("telnet 10.x.x.x 1234"); commands.add("msh");
这里的问题在于:bash -c后面只接受一个完整的命令字符串,你把msh单独作为列表项,它会被当成bash的额外参数,根本不会被telnet执行。而且telnet是交互式程序,就算你把msh塞进bash -c的命令串里(比如"telnet 10.x.x.x 1234; msh")也没用——telnet会一直占据终端,直到你退出它,后面的msh才会执行,这显然不是你想要的效果。
两种可行的解决方案
方案1:用Expect脚本处理交互式命令(推荐)
Expect是专门用来处理交互式终端命令的工具,能帮你自动处理登录、输入命令这类操作,比Java直接处理靠谱多了。
- 先写一个Expect脚本,比如命名为
telnet_msh.exp:
#!/usr/bin/expect # 启动telnet连接 spawn telnet 10.x.x.x 1234 # 等待登录提示符(根据你的实际telnet环境修改,比如可能是"Username:") expect "login:" # 发送用户名,注意结尾要加\r模拟回车 send "你的用户名\r" # 等待密码提示符 expect "Password:" send "你的密码\r" # 等待登录成功后的命令提示符(比如$、#,根据实际情况调整) expect "$" # 发送msh命令 send "msh\r" # 保持交互式会话,如果不需要交互可以换成expect eof interact
- 给脚本加执行权限:
chmod +x telnet_msh.exp
- 然后修改Java代码调用这个脚本:
List<String> commands = new ArrayList<>(); // 替换成你的脚本实际路径 commands.add("/home/user/telnet_msh.exp"); ProcessBuilder pb = new ProcessBuilder(commands); pb.directory(new File("/home/user")); pb.redirectErrorStream(true); Process process = pb.start(); // 读取输出内容 BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } int exitCode = process.waitFor(); System.out.println("命令执行退出码:" + exitCode); // 别忘了关闭资源 reader.close();
方案2:Java直接向telnet进程发送命令
如果你不想用Expect,也可以通过Java的输出流向telnet进程手动发送命令,但这种方式需要处理“等待提示符出现再发送命令”的逻辑,容易出问题,适合简单场景:
List<String> commands = new ArrayList<>(); commands.add("telnet"); commands.add("10.x.x.x"); commands.add("1234"); ProcessBuilder pb = new ProcessBuilder(commands); pb.directory(new File("/home/user")); pb.redirectErrorStream(true); Process process = pb.start(); // 获取telnet的输入流,用来发送命令 OutputStream os = process.getOutputStream(); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os)); // 注意:这里用sleep只是简单模拟等待,实际场景最好是读取输出,匹配到特定提示符再发送命令 // 等待telnet连接建立 Thread.sleep(2000); // 发送用户名 writer.write("你的用户名\r"); writer.flush(); Thread.sleep(1000); // 发送密码 writer.write("你的密码\r"); writer.flush(); Thread.sleep(1000); // 发送msh命令 writer.write("msh\r"); writer.flush(); // 读取telnet的输出 BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } int exitCode = process.waitFor(); System.out.println("命令执行退出码:" + exitCode); // 关闭资源 writer.close(); reader.close();
总结
推荐用Expect脚本的方案,因为它专门处理交互式命令的场景,能避免Java中处理等待、匹配输出的各种坑,稳定性更高。
内容的提问来源于stack exchange,提问作者Anand
相关产品推荐
相关产品推荐

