2010-08-06 6 views
1

J'essaye donc d'exécuter un script shell qui produit beaucoup de sortie (en 100s de Mo) à partir d'un fichier Java. Cela bloque le processus et ne se termine jamais.L'appel d'un script shell à partir de Java se bloque

Cependant, dans le script shell, si je redirige la sortie du script vers un fichier journal ou/dev/null, le fichier Java s'exécute et se termine en un tournemain.

Est-ce à cause de la quantité de données que le programme Java n'achève jamais? Si oui, existe-t-il une documentation en tant que telle? ou y a-t-il une limite à la quantité de données (documentée)?

Voici comment simuler ce scénario.

fichier

Java ressemblera:

import java.io.InputStream; 

public class LotOfOutput { 

    public static void main(String[] args) { 
     String cmd = "sh a-script-which-outputs-huuggee-data.sh"; 
     try { 
      ProcessBuilder pb = new ProcessBuilder("bash", "-c", cmd); 
      pb.redirectErrorStream(true); 
      Process shell = pb.start(); 
      InputStream shellIn = shell.getInputStream(); 
      int shellExitStatus = shell.waitFor(); 
      System.out.println(shellExitStatus); 
      shellIn.close(); 
     } catch (Exception ignoreMe) { 
     } 
    } 
} 

Le script 'a-script-which-outputs-huuggee-data.sh' peut ressembler à:

#!/bin/sh 
# Toggle the line below 
exec 3>&1 > /dev/null 2>&1 

count=1 
while [ $count -le 1000 ] 
do 
     cat some-big-file 
     ((count++)) 
done 

echo 
echo Yes I m done 

bière gratuite pour le droit répondre. :)

Répondre

5

C'est parce que vous ne lisez pas de la sortie Process '.

Selon le class' Javadocs, si vous ne le faites pas, vous pouvez vous retrouver avec un blocage; le processus remplit son tampon d'E/S et attend que le "shell" (ou le processus d'écoute) le lise et le vide. Pendant ce temps, votre processus, qui devrait le faire, bloque l'attente de la sortie du processus.

Appelez le getInputStream() et lisez-le de manière fiable (peut-être à partir d'un autre thread) pour arrêter le blocage du processus.

Jetez également un oeil à Five Java Process Pitfalls et When Runtime.exec() Won't - deux articles informatifs sur les problèmes communs avec Process.

+0

Merci une tonne pour l'intérêt et la réponse !. Vous aviez raison, c'était le problème. – pavanlimo

2

Vous ne lisez jamais le flux d'entrée, donc il bloque probablement parce que le tampon d'entrée est plein.

0

Le tampon d'entrée/sortie a une taille limitée (en fonction du système d'exploitation). Si je me souviens bien ce n'était pas grand ou Windows XP au moins. Essayez de créer un thread qui lit InputStream le plus rapidement possible.

Quelque chose le long de ces lignes:

class StdInWorker 
      implements Worker 
    { 
     private BufferedReader br; 
     private boolean run = true; 
     private int linesRead = 0; 

     private StdInWorker (Process prcs) 
     { 
      this.br = new BufferedReader(
        new InputStreamReader(prcs.getInputStream())); 
     } 

     public synchronized void run() 
     { 
      String in; 
      try { 
       while (this.run) { 
        while ((in = this.br.readLine()) != null) { 
         this.buffer.add(in); 
         linesRead++; 
        } 

        Thread.sleep(50); 
       } 
      } 
      catch (IOException ioe) { 
       ioe.printStackTrace(); 
      } 
      catch (InterruptedException ie) {} 
     } 
    } 
} 
+0

pourriez-vous dire quelle est la classe des travailleurs – KillBill

Questions connexes