首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Runtime.getRuntime().exec(String[])在Java中运行Windows

使用Runtime.getRuntime().exec(String[])在Java中运行Windows
EN

Stack Overflow用户
提问于 2014-09-25 17:07:51
回答 1查看 5.4K关注 0票数 1

我在从java运行这个令人困惑的windows命令时遇到了一点小麻烦,我找不到任何类似于我试图将我的代码作为基础的东西。

基本上,windows命令将杀死与具有CLOSE_WAIT状态的套接字相关的任何PID,并与指定的特定ip:端口相关。我的问题是,我很难让它使用Runtime.getRuntime().exec()运行。

代码语言:javascript
复制
String[] command = {"cmd /c for /f \"tokens=5\" %a in ('netstat -noa -p tcp ^| find /i \"CLOSE_WAIT\" ^| find /i \""+ip+":443\" ') do if not \"%a\"==\"0\" echo taskkill /pid %a"};     
Process runCommand = Runtime.getRuntime().exec(command);
runCommand.waitFor(); 

在执行此操作时,我正在获取错误消息:

类java.io.IOException消息:无法运行程序"C:/ cmd /c for /f“/f "tokens=5”%a in ('netstat -noa -p tcp ^ find /i“/i”ip:443 '),如果不运行“%a”/i "ip:443“,系统将无法找到指定的文件。

任何帮助都将不胜感激。谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-09-25 20:05:45

通过传递一个String[]数组而不是一个字符串,您将告诉系统运行一个.exe文件,该文件的名称包含大约144个字符,其中前13个是cmd /c for /f。显然,没有这个名称的.exe文件。

您可以尝试的一件事是将该单个字符串传递给执行(字符串)方法,而不是传递一个String数组。这可能有效,也可能不起作用,因为Java会将字符串拆分为空格分隔的单词,然后Windows将启发式地尝试找出您想要的内容。

另一种可能有效的方法是包含3个元素的字符串数组:

代码语言:javascript
复制
String[] command = { "cmd", "/c", "for /f \"tokens=5\" %a in ('netstat -noa -p tcp ^| find /i \"CLOSE_WAIT\" ^| find /i \""+ip+":443\" ') do if not \"%a\"==\"0\" echo taskkill /pid %a" };

在我看来,最好的做法是不要依赖cmd.exe来解析命令行参数。我怀疑Java在处理文本方面至少有效率:

代码语言:javascript
复制
Collection<String> pids = new ArrayList<>();

ProcessBuilder p = new ProcessBuilder("netstat.exe", "-noa", "-p", "tcp");
p.inheritIO().redirectOutput(ProcessBuilder.Redirect.PIPE);
Process netstat = p.start();

try (BufferedReader output =
    new BufferedReader(new InputStreamReader(netstat.getOutputStream()))) {

    String line;
    while ((line = output.readLine()) != null) {

        if (line.toUpperCase().contains("CLOSE_WAIT") &&
            line.contains(ip + ":443")) {

            String[] tokens = line.split("\\s+");
            String pid = tokens[4];
            if (!pid.equals("0")) {
                pids.add(pid);
            }
        }
    }
}

if (netstat.waitFor() != 0) {
    throw new IOException("netstat command failed");
}

p.inheritIO();
for (String pid : pids) {
    Process taskkill = p.command("taskkill.exe", "/pid", pid).start();
    taskkill.waitFor();
}

如果使用Java 8,还可以使用流编写更类似管道命令的代码:

代码语言:javascript
复制
ProcessBuilder p = new ProcessBuilder("netstat.exe", "-noa", "-p", "tcp");
p.inheritIO().redirectOutput(ProcessBuilder.Redirect.PIPE);
Process netstat = p.start();

try (BufferedReader output =
    new BufferedReader(new InputStreamReader(netstat.getOutputStream()))) {

    final ProcessBuilder taskkill = new ProcessBuilder().inheritIO();

    output.lines()
        .filter(line -> line.toUpperCase().contains("CLOSE_WAIT") &&
            line.contains(ip + ":443"))
        .map(line -> line.split("\\s+")[4])
        .filter(pid -> !pid.equals("0"))
        .forEach(pid ->
            taskkill.command("taskkill.exe", "/pid", pid).start());
}

if (netstat.waitFor() != 0) {
    throw new IOException("netstat command failed");
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26044263

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档