web-dev-qa-db-ja.com

Javaプログラムから端末でコマンドを実行する方法?

JavaプログラムからFedora 16のターミナルでコマンドを実行する必要があります。

Runtime.getRuntime().exec("xterm"); 

しかし、これは端末を開くだけで、コマンドを実行できません。

私もこれを試しました:

OutputStream out = null;
Process proc = new ProcessBuilder("xterm").start();
out = proc.getOutputStream();  
out.write("any command".getBytes());  
out.flush(); 

しかし、それでも端末を開くことはできますが、コマンドを実行することはできません。それを行う方法についてのアイデアはありますか?

19
phoenix

次のようなbash実行可能ファイルを使用して実行する必要があります。

Runtime.getRuntime().exec("/bin/bash -c your_command");

更新:xav で示唆されているように、代わりに ProcessBuilder を使用することをお勧めします:

String[] args = new String[] {"/bin/bash", "-c", "your_command", "with", "args"};
Process proc = new ProcessBuilder(args).start();
30
SudoRahul

Karthik Tの答えに投票します。コマンドを実行するためにターミナルを開く必要はありません。

例えば、

// file: RunShellCommandFromJava.Java
import Java.io.BufferedReader;
import Java.io.InputStreamReader;

public class RunShellCommandFromJava {

    public static void main(String[] args) {

        String command = "ping -c 3 www.google.com";

        Process proc = Runtime.getRuntime().exec(command);

        // Read the output

        BufferedReader reader =  
              new BufferedReader(new InputStreamReader(proc.getInputStream()));

        String line = "";
        while((line = reader.readLine()) != null) {
            System.out.print(line + "\n");
        }

        proc.waitFor();   

    }
} 

出力:

$ javac RunShellCommandFromJava.Java
$ Java RunShellCommandFromJava
PING http://google.com (123.125.81.12): 56 data bytes
64 bytes from 123.125.81.12: icmp_seq=0 ttl=59 time=108.771 ms
64 bytes from 123.125.81.12: icmp_seq=1 ttl=59 time=119.601 ms
64 bytes from 123.125.81.12: icmp_seq=2 ttl=59 time=11.004 ms

--- http://google.com ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 11.004/79.792/119.601/48.841 ms
11
Scott YAN

実際にxtermセッションからコマンドを実行する必要はありません。直接実行できます:

String[] arguments = new String[] {"/path/to/executable", "arg0", "arg1", "etc"};
Process proc = new ProcessBuilder(arguments).start();

プロセスが入力ストリームに対話的に応答し、値を注入する場合は、前に行ったことを実行します。

OutputStream out = proc.getOutputStream();  
out.write("command\n");  
out.flush();

最後の「\ n」を忘れないでください。ほとんどのアプリは、単一コマンドの入力の終わりを識別するためにそれを使用します。

8
Chris Cooper

他の人が言ったように、xtermなしで外部プログラムを実行できます。ただし、ターミナルウィンドウで実行する場合は、たとえばユーザーが操作できるようにするために、xtermではパラメーターとして実行するプログラムを指定できます。

xterm -e any command

Javaコードでは、これは次のようになります。

String[] command = { "xterm", "-e", "my", "command", "with", "parameters" };
Runtime.getRuntime().exec(command);

または、ProcessBuilderを使用して:

String[] command = { "xterm", "-e", "my", "command", "with", "parameters" };
Process proc = new ProcessBuilder(command).start();
5
user1252434

理由はわかりませんが、何らかの理由で、「/ bin/bash」バージョンが機能しませんでした。代わりに、 ここではOracle Docs。 の例に従って、より単純なバージョンが機能しました

String[] args = new String[] {"ping", "www.google.com"};
Process proc = new ProcessBuilder(args).start();
3
Akash Agarwal

私はこの質問がかなり古いことを知っていますが、ここにProcessBuilder APIをカプセル化する library があります。

1
UpsideDownTree