web-dev-qa-db-fra.com

comment exécuter une commande au terminal à partir du programme Java?

J'ai besoin d'exécuter une commande au terminal dans Fedora 16 à partir d'un programme Java. J'ai essayé d'utiliser

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

mais cela ne fait qu'ouvrir le terminal, je ne peux exécuter aucune commande.

J'ai aussi essayé ceci:

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

mais je ne peux toujours qu'ouvrir le terminal, mais je ne peux pas exécuter la commande . Des idées sur la façon de le faire?

19
phoenix

Vous devez l'exécuter en utilisant bash exécutable comme ceci:

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

Update: Comme suggéré par xav , il est conseillé d'utiliser ProcessBuilder à la place:

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

Je vote pour la réponse de Karthik T. vous n'avez pas besoin d'ouvrir un terminal pour exécuter des commandes. 

Par exemple,

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

    }
} 

Le résultat: 

$ 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

Vous n'avez pas besoin d'exécuter une commande à partir d'une session xterm, vous pouvez l'exécuter directement:

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

Si le processus répond de manière interactive au flux d'entrée et que vous souhaitez injecter des valeurs, effectuez ce que vous avez déjà fait:

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

N'oubliez pas le '\ n' à la fin, car la plupart des applications l'utiliseront pour identifier la fin de l'entrée d'une seule commande.

8
Chris Cooper

Comme d'autres l'ont dit, vous pouvez exécuter votre programme externe sans xterm. Toutefois, si vous souhaitez l’exécuter dans une fenêtre de terminal, par exemple, pour permettre à l'utilisateur d'interagir avec elle, xterm vous permet de spécifier le programme à exécuter en tant que paramètre.

xterm -e any command

En code Java, cela devient:

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

Ou, en utilisant ProcessBuilder:

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

Je ne sais pas pourquoi, mais pour une raison quelconque, la version "/ bin/bash" ne fonctionnait pas pour moi . Au lieu de cela, la version la plus simple a fonctionné, à l'instar de l'exemple donné ici à Oracle Docs.

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

Je sais que cette question est assez ancienne, mais voici une library qui encapsule l’API ProcessBuilder.

1
UpsideDownTree