Skip to content

Archives

  • janvier 2022
  • décembre 2021
  • novembre 2021
  • octobre 2021
  • septembre 2021

Categories

  • Aucune catégorie
Trend RepositoryArticles and guides
Articles

Exécution de commandes shell en Java

On octobre 23, 2021 by admin
  • Introduction
  • Runtime.exec()
  • Exécution d’une commande à partir de String
  • Spécifier le répertoire de travail
  • Utilisation des variables d’environnement
  • Exécution des fichiers .bat et .sh
  • ProcessBuilder
  • ProcessBuilder : Exécution de la commande à partir de chaînes de caractères
  • ProcessBuilder : Spécifier le répertoire de travail
  • ProcessBuilder : Variables d’environnement
  • ProcessBuilder : Exécution des fichiers .bat et .sh
  • Conclusion

Introduction

Dans cet article, nous allons examiner comment nous pouvons tirer parti des classes Runtime et ProcessBuilder pour exécuter des commandes et des scripts shell avec Java.

Nous utilisons les ordinateurs pour automatiser de nombreuses choses dans nos tâches quotidiennes. Les administrateurs système exécutent de nombreuses commandes tout le temps, dont certaines sont très répétitives et nécessitent des changements minimes entre les exécutions.

Ce processus est également mûr pour l’automatisation. Il n’est pas nécessaire de tout exécuter manuellement. En utilisant Java, nous pouvons exécuter des commandes shell uniques ou multiples, exécuter des scripts shell, exécuter le terminal/interrogation de commande, définir des répertoires de travail et manipuler des variables d’environnement par le biais de classes de base.

Runtime.exec()

La classe Runtime en Java est une classe de haut niveau, présente dans chaque application Java unique. Par son intermédiaire, l’application elle-même communique avec l’environnement dans lequel elle se trouve.

En extrayant le runtime associé à notre application via la méthode getRuntime(), nous pouvons utiliser la méthode exec() pour exécuter directement des commandes ou exécuter des fichiers .bat/.sh.

La méthode exec() offre quelques variations surchargées :

  • public Process exec(String command) – Exécute la commande contenue dans command dans un processus séparé.
  • public Process exec(String command, String envp) – Exécute le command, avec un tableau de variables d’environnement. Elles sont fournies sous la forme d’un tableau de Strings, suivant le format name=value.
  • public Process exec(String command, String envp, File dir) – Exécute le command, avec les variables d’environnement spécifiées, à partir du répertoire dir.
  • public Process exec(String cmdArray) – Exécute une commande sous la forme d’un tableau de Strings.
  • public Process exec(String cmdArray, String envp) – Exécute une commande avec les variables d’environnement spécifiées.
  • public Process exec(String cmdarray, String envp, File dir) – Exécute une commande, avec les variables d’environnement spécifiées, à partir du répertoire dir.

Il convient de noter que ces processus sont exécutés en dehors de l’interpréteur et seront dépendants du système.

Ce qui est également à noter est la différence entre String command et String cmdArray. Ils réalisent la même chose. Un command est décomposé en un tableau de toute façon, donc l’utilisation de l’un de ces deux devrait donner les mêmes résultats.

C’est à vous de décider si exec("dir /folder") ou exec(new String{"dir", "/folder"} est ce que vous souhaitez utiliser.

Ecrivons quelques exemples pour voir comment ces méthodes surchargées diffèrent les unes des autres.

Exécution d’une commande à partir de String

Débutons par l’approche la plus simple parmi ces trois :

Process process = Runtime.getRuntime().exec("ping www.stackabuse.com");

L’exécution de ce code exécutera la commande que nous avons fournie au format String. Cependant, nous ne voyons rien lorsque nous exécutons ceci.

Pour valider si cela a été exécuté correctement, nous voudrons mettre la main sur l’objet process. Utilisons un BufferedReader pour jeter un coup d’œil à ce qui se passe:

public static void printResults(Process process) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line = ""; while ((line = reader.readLine()) != null) { System.out.println(line); }}

Maintenant, lorsque nous exécutons cette méthode après la méthode exec(), elle devrait donner quelque chose du genre:

Pinging www.stackabuse.com with 32 bytes of data:Reply from 104.18.57.23: bytes=32 time=21ms TTL=56Reply from 104.18.57.23: bytes=32 time=21ms TTL=56Reply from 104.18.57.23: bytes=32 time=21ms TTL=56Reply from 104.18.57.23: bytes=32 time=21ms TTL=56Ping statistics for 104.18.57.23: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),Approximate round trip times in milli-seconds: Minimum = 21ms, Maximum = 21ms, Average = 21ms

Gardez à l’esprit que nous devrons extraire les informations de processus des instances Process au fur et à mesure des autres exemples.

Spécifier le répertoire de travail

Si vous souhaitez exécuter une commande à partir, disons, d’un certain dossier, nous ferions quelque chose du genre :

Process process = Runtime.getRuntime() .exec("cmd /c dir", null, new File("C:\Users\")); //.exec("sh -c ls", null, new File("Pathname")); for non-Windows usersprintResults(process);

Ici, nous avons fourni à la méthode exec() un command, un null pour les nouvelles variables d’environnement et un new File() qui est défini comme notre répertoire de travail.

L’ajout de cmd /c avant une commande telle que dir mérite d’être noté.

Comme je travaille sous Windows, cela ouvre le cmd et /c exécute la commande suivante. Dans ce cas, c’est dir.

La raison pour laquelle cela n’était pas obligatoire pour l’exemple ping, mais l’est pour cet exemple est joliment répondu par un utilisateur de SO.

L’exécution du morceau de code précédent aboutira à :

Volume in drive C has no label. Volume Serial Number is XXXX-XXXX Directory of C:\Users08/29/2019 05:01 PM <DIR> .08/29/2019 05:01 PM <DIR> ..08/18/2016 09:11 PM <DIR> Default.migrated08/29/2019 05:01 PM <DIR> Public05/15/2020 11:08 AM <DIR> User 0 File(s) 0 bytes 5 Dir(s) 212,555,214,848 bytes free

Regardons comment nous pourrions fournir la commande précédente en plusieurs parties individuelles, au lieu d’une seule Chaîne :

Process process = Runtime.getRuntime().exec( new String{"cmd", "/c", "dir"}, null, new File("C:\Users\")); printResults(process);

L’exécution de ce morceau de code aboutira également à :

Volume in drive C has no label. Volume Serial Number is XXXX-XXXX Directory of C:\Users08/29/2019 05:01 PM <DIR> .08/29/2019 05:01 PM <DIR> ..08/18/2016 09:11 PM <DIR> Default.migrated08/29/2019 05:01 PM <DIR> Public05/15/2020 11:08 AM <DIR> User 0 File(s) 0 bytes 5 Dir(s) 212,542,808,064 bytes free

En définitive, quelle que soit l’approche – utilisation d’un seul String ou d’un tableau de String, la commande que vous saisissez sera toujours décomposée en un tableau avant d’être traitée par la logique sous-jacente.

Celle que vous aimeriez utiliser se résume juste à celle que vous trouvez plus lisible.

Utilisation des variables d’environnement

Regardons comment nous pouvons utiliser les variables d’environnement :

Process process = Runtime.getRuntime().exec( "cmd /c echo %var1%", new String{"var1=value1"}); printResults(process);

Nous pouvons fournir autant de variables d’environnement que nous le souhaitons dans le tableau String. Ici, nous venons d’imprimer la valeur de var1 en utilisant echo.

L’exécution de ce code retournera :

value1

Exécution des fichiers .bat et .sh

Parfois, il est juste beaucoup plus facile de tout décharger dans un fichier et d’exécuter ce fichier au lieu de tout ajouter par programme.

Selon votre système d’exploitation, vous utiliserez soit des fichiers .bat, soit des fichiers .sh. Créons-en un avec le contenu :

echo Hello World

Puis, utilisons la même approche que précédemment :

Process process = Runtime.getRuntime().exec( "cmd /c start file.bat", null, new File("C:\Users\User\Desktop\"));

Cela va ouvrir l’invite de commande et exécuter le fichier .bat dans le répertoire de travail que nous avons défini.

L’exécution de ce code aboutit assez sûrement à :

Avec toutes les signatures surchargées exec() prises en charge, jetons un coup d’œil à la classe ProcessBuilder et à la façon dont nous pouvons exécuter des commandes en l’utilisant.

ProcessBuilder

ProcessBuilder est le mécanisme sous-jacent qui exécute les commandes lorsque nous utilisons la méthode Runtime.getRuntime().exec():

/** * Executes the specified command and arguments in a separate process with * the specified environment and working directory. *...*/public Process exec(String cmdarray, String envp, File dir) throws IOException { return new ProcessBuilder(cmdarray) .environment(envp) .directory(dir) .start();}

JavaDocs pour la classe Runtime

Prendre connaissance de la façon dont la ProcessBuilder prend notre entrée de la méthode exec() et exécute la commande, nous donne une bonne idée de la façon de l’utiliser également.

Il accepte un String cmdarray, et c’est suffisant pour le faire fonctionner. Alternativement, nous pouvons lui fournir des arguments optionnels tels que les String envp et File dir.

Explorons ces options.

ProcessBuilder : Exécution de la commande à partir de chaînes de caractères

Au lieu de pouvoir fournir une seule chaîne de caractères, telle que cmd /c dir, nous devrons la décomposer dans ce cas. Par exemple, si nous voulions lister les fichiers du répertoire C:/Users comme avant, nous ferions :

ProcessBuilder processBuilder = new ProcessBuilder();processBuilder.command("cmd", "/c", "dir C:\Users");Process process = processBuilder.start();printResults(process);

Pour exécuter réellement une Process, nous exécutons la commande start() et assignons la valeur retournée à une instance Process.

L’exécution de ce code donnera :

 Volume in drive C has no label. Volume Serial Number is XXXX-XXXX Directory of C:\Users08/29/2019 05:01 PM <DIR> .08/29/2019 05:01 PM <DIR> ..08/18/2016 09:11 PM <DIR> Default.migrated08/29/2019 05:01 PM <DIR> Public05/15/2020 11:08 AM <DIR> User 0 File(s) 0 bytes 5 Dir(s) 212,517,294,080 bytes free

Mais cette approche n’est pas meilleure que la précédente. Ce qui est utile avec la classe ProcessBuilder, c’est qu’elle est personnalisable. Nous pouvons définir des choses par programme, et pas seulement via des commandes.

ProcessBuilder : Spécifier le répertoire de travail

Au lieu de fournir le répertoire de travail via la commande, définissons-le de manière programmatique:

processBuilder.command("cmd", "/c", "dir").directory(new File("C:\Users\"));

Ici, nous avons défini le répertoire de travail comme étant le même que précédemment, mais nous avons déplacé cette définition hors de la commande elle-même. L’exécution de ce code donnera le même résultat que le dernier exemple.

ProcessBuilder : Variables d’environnement

En utilisant les méthodes de ProcessBuilders, il est facile de récupérer une liste de variables d’environnement sous la forme d’un Map. Il est également facile de définir les variables d’environnement afin que votre programme puisse les utiliser.

Recevons les variables d’environnement actuellement disponibles et ajoutons-en quelques-unes pour une utilisation ultérieure :

ProcessBuilder processBuilder = new ProcessBuilder();Map<String, String> environmentVariables = processBuilder.environment();environmentVariables.forEach((key, value) -> System.out.println(key + value));

Ici, nous avons emballé les variables d’environnement retournées dans un Map et exécuté un forEach() dessus pour imprimer les valeurs sur notre console.

L’exécution de ce code donnera une liste des variables d’environnement que vous avez sur votre machine :

DriverDataC:\Windows\System32\Drivers\DriverDataHerokuPathE:\HerokuProgramDataC:\ProgramData...

Maintenant, ajoutons une variable d’environnement à cette liste et utilisons-la :

environmentVariables.put("var1", "value1");processBuilder.command("cmd", "/c", "echo", "%var1%");Process process = processBuilder.start();printResults(process);

L’exécution de ce code donnera :

value1

Bien sûr, une fois que le programme aura fini de s’exécuter, cette variable ne restera pas dans la liste.

ProcessBuilder : Exécution des fichiers .bat et .sh

Si vous souhaitez exécuter un fichier, là encore, il suffit de fournir à l’instance ProcessBuilder les informations requises:

processBuilder .command("cmd", "/c", "start", "file.bat") .directory(new File("C:\Users\User\Desktop"));Process process = processBuilder.start();

L’exécution de ce code entraîne l’ouverture de l’invite de commande et l’exécution du fichier .bat:

Conclusion

Dans cet article, nous avons exploré des exemples d’exécution de commandes shell en Java. Nous avons utilisé les classes Runtime et ProcessBuilder pour ce faire.

En utilisant Java, nous pouvons exécuter des commandes shell uniques ou multiples, exécuter des scripts shell, exécuter le terminal/interrogation de commande, définir des répertoires de travail et manipuler des variables d’environnement à travers les classes de base.

Laisser un commentaire Annuler la réponse

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Archives

  • janvier 2022
  • décembre 2021
  • novembre 2021
  • octobre 2021
  • septembre 2021

Méta

  • Connexion
  • Flux des publications
  • Flux des commentaires
  • Site de WordPress-FR
  • DeutschDeutsch
  • NederlandsNederlands
  • SvenskaSvenska
  • DanskDansk
  • EspañolEspañol
  • FrançaisFrançais
  • PortuguêsPortuguês
  • ItalianoItaliano
  • RomânăRomână
  • PolskiPolski
  • ČeštinaČeština
  • MagyarMagyar
  • SuomiSuomi
  • 日本語日本語

Copyright Trend Repository 2022 | Theme by ThemeinProgress | Proudly powered by WordPress