• ベストアンサー

Java getRuntime().exec() でのパイプ利用に関して。

はじめまして。 JavaのgetRuntime().execでコマンドプロンプトを動かそうと思っております。 コマンドプロンプトで「netstat -an | find "***"」というコマンドをJavaから実行したいと思っています。 しかし、Javaではパイプ(=|)を利用したコマンドは実行できない。 ということを検索してたどり着きました。 例などでは、「シェル」を利用しろ。などとかかれていましたが何をどうすればいいかわかりません。 String[] s = {"netstat","-an"}; Process process = Runtime.getRuntime().exec(s); 今は上記の状態で「netstat -an」が実行されています。 どうすれば「find "***"」で***の検索をかけることができるでしょうか? どうぞ、よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • akomot
  • ベストアンサー率50% (2/4)
回答No.3

String[] s = {"cmd.exe", "/c", "dir c: | find /i "***"}; Process process = Runtime.getRuntime().exec(s); InputStream is = process.getInputStream(); こんな感じで使っていますが、だめですか?

nukiharu
質問者

お礼

お返事ありがとうございます。 String[] s = {"cmd.exe", "/c", "netstat -an | find "\"***\""}; に変更したら無事に実行し、結果を得ることができました。 ありがとうございます。 ところで、重ね重ねの質問になってしまうのですが、上で使用されている「cmd.exe」と「/c」これらの意味(前者はcmdの起動だと思いますが。)と必要な理由を教えていただけないでしょうか?

その他の回答 (4)

  • SN1701
  • ベストアンサー率76% (16/21)
回答No.5

ほとんど問題は解決しているようですが,'cmd.exe /c'が「必要な理由」についてだけ... 端的に言うと,パイプ('|')やリダイレクト('<'や'>')を解釈して,実行前に,プログラム同士をつなげたり,出力をファイルにまわしたりする準備をしているのが,cmd.exe だからです. Java から,Runtime.getRuntime().exec(...)で実行した場合,cmd.exeを経由せず,直接実行ファイルを実行しますのでパイプ等は解釈されないことになります. というわけで,明示的にcmd.exeを経由して動かしてやれば,パイプが解釈されるというわけです. ちなみに,cmd.exe のような仕事をするプログラムのことを「シェル」と呼びます.

nukiharu
質問者

お礼

お返事ありがとうございます。 なるほど。 普通に「netstat -an」のようなコマンドを入力するだけで起動やら準備までやってくれるものだと思っていました。 大変参考になりました。ありがとうございます。

  • akomot
  • ベストアンサー率50% (2/4)
回答No.4

ANo.3です。 cmd.exeはコマンドプロンプの起動です。/cはコマンドプロンプトのオプションで付けるとコマンドを実行後コマンドプロンプトが終了します。 コマンドプロンプトで「cmd /?」を打ち込むといろいろオプションが確認できますので興味があれば見てみてください。

nukiharu
質問者

お礼

たびたびありがとうございます。 なるほど、cmdに関する知識が全然足りなかったみたいですね。 次からはご迷惑をおかけしないようにきちんと調べてから質問しますね。 本当にありがとうございました。

回答No.2

たぶん無理だと思いますが、(試してもいません。) netstatのProcessオブジェクトからgetOutputStreamメソッドで出力ストリームを取得し、出力ストリームから取得した結果を findのProcessオブジェクトからgetInputStreamメソッドで取得した入力ストリームへ入れる… というのはどうでしょうか… おそらくダメだから、 >Javaではパイプ(=|)を利用したコマンドは実行できない。 >ということを検索してたどり着きました。 となっているのでしょうけど…

nukiharu
質問者

お礼

たびたびありがとうございます。 上記の方法を試すプラグラミング能力がないわけですが・・・ import java.io.*; public class Gaibu { public static void main(String[] args) { try { String[] s1 = {"netstat","-an"}; Process process = Runtime.getRuntime().exec(s1); InputStream is = process.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String line; while ((line = br.readLine()) != null) { System.out.println(line); } } catch (Exception e) { e.printStackTrace(); } } } これを実行した結果(→netstat -anでport表示)をどこかに格納してその結果の中へfindコマンドを実行できる。ということでしょうか? >おそらくダメだから、 >>Javaではパイプ(=|)を利用したコマンドは実行できない。 >>ということを検索してたどり着きました。 >となっているのでしょうけど… というのは、「netstat -an | find "***"」のように二つのコマンドをパイプを利用して、一回で利用することができない。 ということなので、「netstat -an」の結果をどこかに保持し、それに対して「find "***"」(*は検索したいポート番号)のコマンドを実行することができるのならば、可能だと思います。 この際結果の保持を形として現れない一時記憶が理想なので・・・ 結果をファイルとして出力→それに対して「find」コマンドというのは避けたいかな。とか・・思ってます。 親切に返信心から感謝いたしております。

回答No.1

コマンドプロンプトなので、Windowsのことで良いのかな? Windowsなら netstat -an | find "***" とファイルに書いて、拡張子を「bat」にしてファイルに保存し、 javaからは上記batファイルを実行すれば良いと思います。 実行結果は、java.lang.ProcessクラスのgetOutputStreamメソッド、getErrorStreamメソッドで取るか、ファイルI/Oかな。

nukiharu
質問者

お礼

お返事ありがとうございます。 batファイルで実際にできるかどうかを確認してみます。 できることなら、batファイルではなくJavaのプログラム内での実行をしたいのですが、それは無理なのでしょうか?

専門家に質問してみよう