使用Runtime.getRuntime().exec(字符串[])在Java中运行Windows命令
我在java中运行这个令人困惑的windows命令时遇到了一点问题,我找不到任何类似于我试图基于代码所做的事情 基本上,windows命令会杀死与具有CLOSE_WAIT状态的套接字以及与指定的特定ip:端口相关的任何PID。我的问题是我很难使用Runtime.getRuntime().exec()运行它 执行此操作时,我当前收到错误消息: 类java.io.IOException消息:无法为运行程序“C:/cmd/C” /f“tokens=5”%a in('netstat-noa-ptcp^ | find/i“CLOSE_WAIT”^| 查找/i“ip:443”)如果不是“%a”==“0”echo taskkill/pid%a,则执行以下操作: CreateProcess错误=2,系统找不到指定的文件使用Runtime.getRuntime().exec(字符串[])在Java中运行Windows命令,java,windows,command-line,Java,Windows,Command Line,我在java中运行这个令人困惑的windows命令时遇到了一点问题,我找不到任何类似于我试图基于代码所做的事情 基本上,windows命令会杀死与具有CLOSE_WAIT状态的套接字以及与指定的特定ip:端口相关的任何PID。我的问题是我很难使用Runtime.getRuntime().exec()运行它 执行此操作时,我当前收到错误消息: 类java.io.IOException消息:无法为运行程序“C:/cmd/C” /f“tokens=5”%a in('netstat-noa-ptcp^
任何帮助都将不胜感激。谢谢 通过传递字符串[]数组而不是单个字符串,您告诉系统运行一个.exe文件,该文件的名称包含大约144个字符,其中前13个字符是
cmd/c for/f
。显然,没有具有该名称的.exe文件
您可以尝试将单个字符串传递给方法,而不是传递字符串数组。这可能有效,也可能无效,因为Java会将字符串拆分为以空格分隔的单词,然后Windows会试探性地尝试找出您想要的内容
另一种可能有效的方法是包含3个元素的字符串数组:
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至少在处理文本方面同样有效:
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();
}
首先尝试在
cmd
中执行该命令,并检查该命令是否有效!您是否尝试过使用windows命令创建.bat文件并通过runtime.exec()运行.bat?嗯,事实上我刚刚做了,我收到了一条“|此时出乎意料”的错误消息。我不想通过bat文件运行它,因为这会给我的代码库增加一些混乱,我需要传递我想要关闭套接字的系统的ip。我尽量少保存文件。
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();
}
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");
}