【问题标题】:Can not get the value of command execution "lsof"无法获取命令执行“lsof”的值
【发布时间】:2015-09-11 18:24:27
【问题描述】:

这是我的程序的样子

Reference

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class ExecuteShellCommand {

  public static void main(final String[] args) {

    final ExecuteShellCommand obj = new ExecuteShellCommand();
    final String ping = "ping -c 3 google.com";
    final String lsof = "lsof | wc -l";
    final String output = obj.executeCommand(ping);
    System.out.println(output);
  }

  private String executeCommand(final String command) {
    final StringBuffer output = new StringBuffer();
    final Process p;
    try {
      p = Runtime.getRuntime().exec(command);
      final int waitForStatus = p.waitFor();
      System.out.println("waitForStatus=" + waitForStatus);
      final BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
      String line = "";
      while ((line = reader.readLine()) != null) {
        output.append(line + "\n");
      }
    } catch (final Exception e) {
      e.printStackTrace();
    }
    return output.toString();
  }
}

当我运行这个程序时,我的输出什么都没有

Process finished with exit code 0

但是,当我在我的机器上运行相同的命令时,我看到了

$ lsof | wc -l
    8045

这里有什么问题?

更新 当我将final String ping = "ping -c 3 google.com"; 作为命令运行时,我看到输出为

waitForStatus=0
PING google.com (216.58.192.14): 56 data bytes
64 bytes from 216.58.192.14: icmp_seq=0 ttl=59 time=7.412 ms
64 bytes from 216.58.192.14: icmp_seq=1 ttl=59 time=8.798 ms
64 bytes from 216.58.192.14: icmp_seq=2 ttl=59 time=6.968 ms

--- google.com ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 6.968/7.726/8.798/0.779 ms

但是对于final String lsof = "lsof | wc -l";,我明白了

waitForStatus=1


Process finished with exit code 0

【问题讨论】:

  • 你能从任何其他进程获得输出吗? p.waitFor() 返回的存在状态是什么?有没有错误输出?
  • waitForStatus=1。出了点问题
  • 尝试不使用| wc -l

标签: java lsof


【解决方案1】:

管道| 是个问题。以下修复了它

final String[] lsof = {
        "/bin/sh",
        "-c",
        "lsof | wc -l"
    };

这是回答https://stackoverflow.com/a/5928316/379235

【讨论】:

    【解决方案2】:

    您不应使用 Runtime.exec。它已经过时了十多年。它的替换是ProcessBuilder

    正如您所发现的,您不能传递管道(或任何重定向),因为它不是命令的一部分;它的功能是由 shell 提供的。

    但是,您根本不需要管道。 Java 在做同样的工作方面同样出色:

    long count;
    
    ProcessBuilder builder = new ProcessBuilder("lsof");
    builder.inheritIO().redirectOutput(ProcessBuilder.Redirect.PIPE);
    
    try (BufferedReader reader = new BufferedReader(
            new InputStreamReader(builder.start().getInputStream())) {
        count = reader.lines().count();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-15
      • 2020-06-19
      • 2016-08-20
      • 2020-03-08
      • 1970-01-01
      相关资源
      最近更新 更多