我在从java运行这个令人困惑的windows命令时遇到了一点小麻烦,我找不到任何类似于我试图将我的代码作为基础的东西。
基本上,windows命令将杀死与具有CLOSE_WAIT状态的套接字相关的任何PID,并与指定的特定ip:端口相关。我的问题是,我很难让它使用Runtime.getRuntime().exec()运行。
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“,系统将无法找到指定的文件。
任何帮助都将不胜感激。谢谢!
发布于 2014-09-25 20:05:45
通过传递一个String[]数组而不是一个字符串,您将告诉系统运行一个.exe文件,该文件的名称包含大约144个字符,其中前13个是cmd /c for /f。显然,没有这个名称的.exe文件。
您可以尝试的一件事是将该单个字符串传递给执行(字符串)方法,而不是传递一个String数组。这可能有效,也可能不起作用,因为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();
}如果使用Java 8,还可以使用流编写更类似管道命令的代码:
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");
}https://stackoverflow.com/questions/26044263
复制相似问题