0

ポート番号を提供するJavaアプリケーションを作成しています。特定のポートでリッスンしているアプリケーションの。

ポート番号を取得したい。ポート 10001 でリッスンしているアプリケーションの

Process p = Runtime.getRuntime().exec("lsof -i:10001 | awk '{print $2}'");
InputStream is=p.getInputStream();
byte b[]=new byte[is.available()];
is.read(b,0,b.length);
System.out.println(new String(b));
p.waitFor();
System.out.println("exit: " + p.exitValue());
p.destroy();

lsof -i:10001 | awk '{print $2}'これをシェルで実行すると、出力が得られます

PID
8092

しかし、Javaアプリケーションでは、それは私に与えますexit: 1. java で実行しないのはなぜですか? また、ポート番号のみを取得できますか? つまり、PID 8091私が欲しいのではなく8092

4

2 に答える 2

1

これを試して

String[] cmd = { "/bin/sh", "-c", "lsof -i:10001 | awk '{print $2}'" };
Process p = Runtime.getRuntime.exec(cmd);

つまり、-c オプションを指定してシェルを実行します。これは、3 番目のパラメーターがシェル スクリプト文字列であることを意味します。

于 2013-09-05T10:15:32.277 に答える
0

Runtime.execパイプを直接使用することはできません(/bin/shプロセスを実行し、パイプを処理することによってのみ)。lsofを使用するよりも、 を外部プロセスとして実行し、Java コードで 2 番目のフィールドを抽出する方が適切な場合がありますawk

また、このavailable()メソッドは、ブロックせずに現在提供できるとストリームが認識しているバイト数を返しますが、それ以上のバイトが後で利用可能になるとは限りません。「このメソッドの戻り値を使用して、このストリーム内のすべてのデータを保持するためのバッファを割り当てることは決して正しくありません。」( InputStream JavaDoc からの引用)。EOF に到達するまで読み続ける必要があります。Apache commons-io は、これを支援する便利なユーティリティ メソッドを提供します。

ProcessBuilder pb = new ProcessBuilder("lsof", "-i:10001");
pb.redirectError(ProcessBuilder.Redirect.to(new File("/dev/null")));
Process p = pb.start();
try {
  List<String> lines = IOUtils.readLines(p.getOutputStream());
  if(lines.size() > 1) {
    // more than one line, so the second (i.e. lines.get(1)) will have the info
    System.out.println(lines.get(1).split("\s+")[1]);
  } else {
    System.out.println("Nothing listening on port 10001");
  }
} finally {
  p.getOutputStream().close();
  p.waitFor();
}
于 2013-09-05T11:09:36.627 に答える