Voulez-vous appeler une commande shell Linux à partir de Java

J’essaie d’exécuter des commandes Linux à partir de Java en utilisant la redirection (> &) et les pipes (|). Comment Java peut-il invoquer les commandes csh ou bash ?

J’ai essayé d’utiliser ceci:

 Process p = Runtime.getRuntime().exec("shell command"); 

Mais ce n’est pas compatible avec les redirections ou les tuyaux.

exec n’exécute pas de commande dans votre shell

essayer

 Process p = Runtime.getRuntime().exec(new Ssortingng[]{"csh","-c","cat /home/narek/pk.txt"}); 

au lieu.

EDIT :: Je n’ai pas de csh sur mon système donc j’ai utilisé bash à la place. Les suivants ont fonctionné pour moi

 Process p = Runtime.getRuntime().exec(new Ssortingng[]{"bash","-c","ls /home/XXX"}); 

Utilisez ProcessBuilder pour séparer les commandes et les arguments au lieu des espaces. Cela devrait fonctionner indépendamment du shell utilisé:

 import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; public class Test { public static void main(final Ssortingng[] args) throws IOException, InterruptedException { //Build command List commands = new ArrayList(); commands.add("/bin/cat"); //Add arguments commands.add("/home/narek/pk.txt"); System.out.println(commands); //Run macro on target ProcessBuilder pb = new ProcessBuilder(commands); pb.directory(new File("/home/narek")); pb.redirectErrorStream(true); Process process = pb.start(); //Read output SsortingngBuilder out = new SsortingngBuilder(); BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream())); Ssortingng line = null, previous = null; while ((line = br.readLine()) != null) if (!line.equals(previous)) { previous = line; out.append(line).append('\n'); System.out.println(line); } //Check result if (process.waitFor() == 0) { System.out.println("Success!"); System.exit(0); } //Abnormal termination: Log command parameters and output and throw ExecutionException System.err.println(commands); System.err.println(out.toSsortingng()); System.exit(1); } } 

S’appuyant sur l’exemple de @ Tim pour créer une méthode autonome:

 import java.io.BufferedReader; import java.io.File; import java.io.InputStreamReader; import java.util.ArrayList; public class Shell { /** Returns null if it failed for some reason. */ public static ArrayList command(final Ssortingng cmdline, final Ssortingng directory) { try { Process process = new ProcessBuilder(new Ssortingng[] {"bash", "-c", cmdline}) .redirectErrorStream(true) .directory(new File(directory)) .start(); ArrayList output = new ArrayList(); BufferedReader br = new BufferedReader( new InputStreamReader(process.getInputStream())); Ssortingng line = null; while ( (line = br.readLine()) != null ) output.add(line); //There should really be a timeout here. if (0 != process.waitFor()) return null; return output; } catch (Exception e) { //Warning: doing this is no good in high quality applications. //Instead, present appropriate error messages to the user. //But it's perfectly fine for prototyping. return null; } } public static void main(Ssortingng[] args) { test("which bash"); test("find . -type f -printf '%T@\\\\t%p\\\\n' " + "| sort -n | cut -f 2- | " + "sed -e 's/ /\\\\\\\\ /g' | xargs ls -halt"); } static void test(Ssortingng cmdline) { ArrayList output = command(cmdline, "."); if (null == output) System.out.println("\n\n\t\tCOMMAND FAILED: " + cmdline); else for (Ssortingng line : output) System.out.println(line); } } 

(L’exemple de test est une commande qui répertorie tous les fichiers d’un répertoire et de ses sous-répertoires, de manière récursive, dans l’ordre chronologique .)

Au fait, si quelqu’un peut me dire pourquoi j’ai besoin de quatre et huit antislashs au lieu de deux et quatre, je peux apprendre quelque chose. Il y a un autre niveau d’évanouissement que ce que je compte.

Edit: Je viens d’essayer ce même code sous Linux, et il s’avère que j’ai besoin de deux fois moins de barres obliques inverses dans la commande de test! (C’est-à-dire le nombre attendu de deux et quatre.) Maintenant, ce n’est plus simplement bizarre, c’est un problème de portabilité.