Java: Commandes Shell avec redirection


J'essaie d'exécuter la redirection dans le shell en utilisant java, mais j'obtiens un file1.txt vide pour la commande: ls -all > file1.txt.

Bien que ls -all soit exécuté correctement.

commandLine est de type String et a la commande que je voudrais exécuter.
par exemple String commandLine = "ls -all";

Extrait de code(C'est la section pertinente du code) :

   StringBuilder output = new StringBuilder();
   Runtime runtime = Runtime.getRuntime();
    Process process = runtime.exec(new String[]{"/bin/sh", "-c", commandLine});
    process.waitFor();

    try {
         BufferedReader reader = 
           new BufferedReader(new InputStreamReader(process.getInputStream()));

          String line;          
          line = "";
          while ((line = reader.readLine())!= null) {
              output.append(line);
              output.append("\n");
          }
    } 
    catch(Exception ex) {
      ex.printStackTrace();
    } 
    finally {
      process.destroy();
    }

Enfin, je traite la sortie de l'instance output.
En outre, je veux exécuter la commande similaire à {[7] } mais cela me donne aussi une réponse vide !

Author: Prameet Singh Kohli, 2016-02-07

1 answers

Réponse Courte

Vous lisez stdout, qui est vide car vous avez redirigé stdout vers /dev/null. Utiliser getErrorStream() au lieu de getInputStream() pour obtenir stderr.

stdout et stderr

Il y a 2 flux de sortie de chaque processus, stdout et stderr. Dans le cas du curl -v http://www.centos.org mentionné, les 2 flux de sortie seraient les flux suivants:

stdout:

<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.6.3</center>
</body>
</html>

stderr:

* Rebuilt URL to: http://www.centos.org/
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 85.12.30.226...
* Connected to www.centos.org (85.12.30.226) port 80 (#0)
> GET / HTTP/1.1
> Host: www.centos.org
> User-Agent: curl/7.43.0
> Accept: */*
> 
< HTTP/1.1 301 Moved Permanently
< Server: nginx/1.6.3
< Date: Thu, 19 May 2016 15:31:03 GMT
< Content-Type: text/html
< Content-Length: 184
< Connection: keep-alive
< Location: https://www.centos.org/
< 
{ [184 bytes data]
100   184  100   184    0     0   1184      0 --:--:-- --:--:-- --:--:--  1187
* Connection #0 to host www.centos.org left intact

Le > opérateur de redirection uniquement stdout, mais stderr sera intact.

Exécution dans le terminal

Dans les terminaux, vous voyez généralement stdout et stderr mélangés. Donc, si vous exécutez curl -v http://www.centos.org > /dev/null, puis stdout serez redirigé vers /dev/null, mais vous aurez quand même la sortie de stderr. C'est ce que vous observez, quand vous dites que "exécuter la même commande bash donne [...] sortie."

Exécution depuis Java

L'exécution d'une commande à partir de Java, en revanche, gardera les deux flux séparés. Le flux stdout peut être obtenu en utilisant process.getInputStream(), et stderr peut être obtenu en utilisant process.getErrorStream().

Vous utilisez l'ancien (stdout), mais puisque stdout est redirigé vers /dev/null dans votre exemple (curl -v http://www.centos.org), il n'est pas surprenant que vous ne voyiez aucune sortie.

La seule sortie que vous pourriez obtenir serait stderr. Pour cela, vous devez remplacer process.getInputStream() par process.getErrorStream().

Vide file1.txt

Vous indiquez dans les commentaires que le fichier file1.txt est vide après avoir exécuté une commande comme celle-ci ls -all > file1.txt à partir de Java.

La raison la plus probable est que l'exécution de ls a effectivement échoué, mais vous ne voyez pas le message d'erreur car il est imprimé sur stderr - que vous ne lisez jamais. Vous indiquez que la même commande fonctionne correctement dans le terminal, mais que les environnements d'exécution sont différents (variables d'environnement différentes, répertoire de travail différent, etc.), ce qui peut faire échouer la même commande. Alors lisez stderr pour obtenir le message d'erreur.

Une autre raison possible pour un vide file1.txt est que vous vérifiez un fichier différent car le répertoire de travail vous est inconnu. M'est arrivé plus d'une fois que j'ai vérifié le fichier incorrect! Vérifiez l'horodatage pour vous assurer que c'est le bon fichier.

 2
Author: mastov, 2016-05-19 15:57:43