Maison >Java >javaDidacticiel >Comment exécuter de manière fiable des commandes Bash et capturer leur sortie en Java ?

Comment exécuter de manière fiable des commandes Bash et capturer leur sortie en Java ?

Susan Sarandon
Susan Sarandonoriginal
2024-12-19 11:19:14697parcourir

How to Reliably Execute Bash Commands and Capture Their Output in Java?

Exécution de commandes avec des flux d'entrée/sortie en Java

Aperçu du problème

Vous souhaitez créer un programme Java qui exécute des commandes dans un shell bash et récupère leur production. Cependant, vous rencontrez des problèmes avec plusieurs flux de sortie qui ne fonctionnent pas après la première lecture et l'exception « Tuyau cassé ».

Solution

1. Utilisez ProcessBuilder :

Remplacer Process process = Runtime.getRuntime().exec("/bin/bash"); with :

ProcessBuilder builder = new ProcessBuilder("/bin/bash");
builder.redirectErrorStream(true);
Process process = builder.start();

ProcessBuilder permet de rediriger l'erreur standard vers la sortie standard, éliminant ainsi le besoin de threads séparés pour stderr et stdout.

2. Attendez la fin de la sortie :

La lecture des boucles à partir du flux de sortie (reader.readline()) se bloquera jusqu'à ce que le processus se termine ou envoie la fin du fichier. Pour éviter les blocages, assurez-vous que les boucles itèrent uniquement lorsque le résultat attendu a été reçu.

3. Utilisez une « ligne magique » pour marquer la fin de la sortie :

Pour déterminer de manière fiable quand la sortie de la commande exécutée est terminée, envisagez d'écrire une ligne spécifique (par exemple, "--EOF--") pour signaler la fin de la sortie. Cette technique, illustrée dans l'extrait de code ci-dessous, permet de gérer les scénarios dans lesquels le processus ne se termine pas par un caractère de nouvelle ligne :

while (scan.hasNext()) {
    String input = scan.nextLine();
    if (input.trim().equals("exit")) {
        writer.write("exit\n");
    } else {
        writer.write("((" + input + ") && echo --EOF--) || echo --EOF--\n");
    }
    writer.flush();

    line = reader.readLine();
    while (line != null && ! line.trim().equals("--EOF--")) {
        System.out.println("Stdout: " + line);
        line = reader.readLine();
    }
    if (line == null) {
        break;
    }
}

Limitations

  • La solution est limitée dans gérer les commandes qui attendent l'entrée de l'utilisateur ou génèrent une sortie sans retour à la ligne.
  • Cela suppose que la commande génère un --EOF-- line.
  • L'utilisation de parenthèses dans la commande écrite peut provoquer des erreurs de syntaxe dans bash.

Remarque : Cette approche garantit que toutes les sorties de la commande exécutée est capturé avant qu’une autre commande ne soit entrée. Il permet l'exécution continue de commandes dans une tâche planifiée threadée sans rencontrer l'exception « Tuyau cassé ».

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn