Javaコード実行shellコマンドの実現


本論文は、javaコードを使用してshellコマンドを実行する2つの方法を説明し、まずRuntimeクラスを使用してexce方法を起動し、次にProcesssBuiderのインスタンスを使用してより柔軟な方法を実現する。
1.環境準備
shell命令を実行する前に、jvm底部のオペレーティングシステムを取得し、同時に汎用消費ストリームのクラスを定義する必要があります。
1.1.オペレーティングシステムの依存性
フィールドを作成してshellコマンドを実行する前に、jvmが具体的にどのオペレーティングシステムを実行しているかを確認する必要があります。Windowsがshell命令を実行するのはcmd.exeであるのに対し、他のOSが標準shellをリリースするのはshellであるshellはshである。

boolean isWindows = System.getProperty("os.name").toLowerCase().startsWith("windows");
1.2.入出力
また、プロセスの入出力ストリームを接続する方法が必要です。出力フローが消費プロセスによって成功に戻るまでは、保留されます。以下、汎用タイプStream Gobler消費InputStreamを実現する。

private static class StreamGobbler implements Runnable {
  private InputStream inputStream;
  private Consumer<String> consumer;
 
  public StreamGobbler(InputStream inputStream, Consumer<String> consumer) {
    this.inputStream = inputStream;
    this.consumer = consumer;
  }
 
  @Override
  public void run() {
    new BufferedReader(new InputStreamReader(inputStream)).lines()
     .forEach(consumer);
  }
}
このクラスは、Runnableインターフェースを実現し、任意のExectorによって実行できることを意味する。
2.Runtime.exec()実行
Runtime.exec()方法は新しいサブプロセスを生成する簡単な方法ですが、カスタマイズはできません。以下の例は、ユーザディレクトリのディレクトリリストを一覧表示し、コンソールに印刷します。

String homeDirectory = System.getProperty("user.home");
Process process;
if (isWindows) {
  process = Runtime.getRuntime()
   .exec(String.format("cmd.exe /c dir %s", homeDirectory));
} else {
  process = Runtime.getRuntime()
   .exec(String.format("sh -c ls %s", homeDirectory));
}
StreamGobbler streamGobbler = 
 new StreamGobbler(process.getInputStream(), System.out::println);
Executors.newSingleThreadExecutor().submit(streamGobbler);
int exitCode = process.waitFor();
assert exitCode == 0;
3.ProcesssBuider実行
第二の方法はProcesssBuiderを使用する。これはRuntime法よりも優れています。細かい部分をカスタマイズできるからです。
たとえば:
  • は、Shellコマンドを実行しているワークディレクトリを変更し、builder.directory()方法を使用して
  • は、環境変数
  • としてカスタムキーペアを設定します。
  • リダイレクト入力および出力ストリーム値カスタムストリーム
  • は、Bild.inheritio()の方法を使用して、これらを現在のJVMプロセスのストリーム中の
  • に継承する。
    
    ProcessBuilder builder = new ProcessBuilder();
    if (isWindows) {
      builder.command("cmd.exe", "/c", "dir");
    } else {
      builder.command("sh", "-c", "ls");
    }
    builder.directory(new File(System.getProperty("user.home")));
    Process process = builder.start();
    StreamGobbler streamGobbler = 
     new StreamGobbler(process.getInputStream(), System.out::println);
    Executors.newSingleThreadExecutor().submit(streamGobbler);
    int exitCode = process.waitFor();
    assert exitCode == 0;
    4.まとめ
    本論文ではShell命令を実行する2つの異なる方法を紹介した。通常、カスタム派生フローの実行が必要である場合、例えば、その作業ディレクトリの変更が必要である場合、Process Buiderを使用することが考慮されるべきである。
    以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。