J'utilise le runtime pour exécuter des commandes d'invite de commande à partir de mon programme Java. Cependant, je ne sais pas comment je peux obtenir la sortie renvoyée par la commande.
Voici mon code:
Runtime rt = Runtime.getRuntime();
String[] commands = {"system.exe", "-send" , argument};
Process proc = rt.exec(commands);
J'ai essayé de faire System.out.println(proc);
mais cela n'a rien retourné. L'exécution de cette commande doit renvoyer deux nombres séparés par un point-virgule. Comment pourrais-je obtenir cela dans une variable à imprimer?
Voici le code que j'utilise maintenant:
String[] commands = {"system.exe", "-get t"};
Process proc = rt.exec(commands);
InputStream stdIn = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(stdIn);
BufferedReader br = new BufferedReader(isr);
String line = null;
System.out.println("<OUTPUT>");
while ((line = br.readLine()) != null)
System.out.println(line);
System.out.println("</OUTPUT>");
int exitVal = proc.waitFor();
System.out.println("Process exitValue: " + exitVal);
Mais je n'obtiens rien comme sortie, mais quand j'exécute cette commande moi-même, cela fonctionne très bien.
pwd && ls
pas seulement un seul fichier, lorsque vous faites cela dans un shell, il exécute à la fois les exécutables/bin/pwd
et/bin/ls
. Si vous voulez faire des choses comme ça dans java, vous devrez faire quelque chose comme{"/bin/bash","-c", "pwd && ls"}
. Vous n'avez probablement plus la question mais d'autres personnes pourraient le faire, alors j'ai pensé que je pourrais y répondre.stdout
et lastderr
sortie. Si vous ne les écoutez pas simultanément, l'un d'eux se remplira pendant que vous lirez l'autre. Le programme que vous écoutez bloquera alors les tentatives d'écriture dans le tampon rempli, tandis qu'à l'autre extrémité, votre programme bloquera les tentatives de lecture à partir d'un tampon qui ne reviendra jamaisEOF
. Vous devez lire les deux flux simultanément.Un moyen plus rapide est le suivant:
Ce qui est essentiellement une version condensée de ceci:
Je sais que cette question est ancienne mais je poste cette réponse car je pense que cela peut être plus rapide.
la source
\A
dans une regex signifie début de chaîne et j'ai dû échapper à la barre oblique.En plus d'utiliser
ProcessBuilder
comme suggéré Senthil, assurez-vous de lire et d'implémenter toutes les recommandations de When Runtime.exec () ne le fera pas .la source
ProcessBuilder
comme maintenant recommandé deux fois. En utilisant aProcessBuilder
, il est possible de fusionner les flux de sortie et d'erreur pour faciliter la consommation des deux à la fois.Si vous utilisez déjà Apache commons-io disponible sur le chemin de classe, vous pouvez utiliser:
la source
Nous pouvons également utiliser des flux pour obtenir la sortie de commande:
la source
Réponse @Senthil et @Arend ( https://stackoverflow.com/a/5711150/2268559 ) mentionnée
ProcessBuilder
. Voici l'exemple utilisantProcessBuilder
avec la spécification des variables d'environnement et du dossier de travail pour la commande:la source
Au moment de la rédaction de cet article, toutes les autres réponses contenant du code peuvent entraîner des blocages.
Les processus ont une mémoire tampon limitée pour
stdout
et lastderr
sortie. Si vous ne les écoutez pas simultanément, l'un d'entre eux se remplira pendant que vous essayez de lire l'autre. Par exemple, vous pourriez être en attente de lecturestdout
pendant que le processus attend pour écrirestderr
. Vous ne pouvez pas lire à partir dustdout
tampon car il est vide et le processus ne peut pas écrire dans lestderr
tampon car il est plein. Vous vous attendez l'un l'autre pour toujours.Voici un moyen possible de lire la sortie d'un processus sans risque de blocage:
La clé est d'utiliser
ProcessBuilder.redirectErrorStream(true)
ce qui redirigerastderr
dans lestdout
flux. Cela vous permet de lire un seul flux sans avoir à alterner entrestdout
etstderr
. Si vous souhaitez l'implémenter manuellement, vous devrez consommer les flux dans deux threads différents pour vous assurer de ne jamais bloquer.la source
Si vous écrivez sur Kotlin, vous pouvez utiliser:
la source
Adapté de la réponse précédente:
la source
À peu près la même chose que les autres extraits de cette page, mais il suffit d'organiser les choses sur une fonction , nous y voilà ...
La fonction Classe:
la source
Essayez de lire le
InputStream
du runtime:Vous devrez peut-être également lire le flux d'erreur (
proc.getErrorStream()
) si le processus imprime une sortie d'erreur. Vous pouvez rediriger le flux d'erreur vers le flux d'entrée si vous utilisezProcessBuilder
.la source