0

Here is what my program looks like

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();
  }
}

When I run this program my output is nothing

Process finished with exit code 0

However, when I run the same command on my machine, I see

$ lsof | wc -l
    8045

What is the problem here?

UPDATE When I run final String ping = "ping -c 3 google.com"; as command I see output as

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

but for final String lsof = "lsof | wc -l";, I get

waitForStatus=1


Process finished with exit code 0
daydreamer
  • 87,243
  • 191
  • 450
  • 722

2 Answers2

1

pipe | was an issue. The following fixed it

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

This is answered https://stackoverflow.com/a/5928316/379235

Community
  • 1
  • 1
daydreamer
  • 87,243
  • 191
  • 450
  • 722
1

You should not use Runtime.exec. It has been obsolete for over ten years. Its replacement is ProcessBuilder.

As you've discovered, you can't pass a pipe (or any redirection) because it's not part of the command; its functionality is provided by the shell.

However, you don't need the pipe at all. Java is every bit as good at doing the same work:

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();
}
VGR
  • 40,506
  • 4
  • 48
  • 63