IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

executer cmd linux en Java


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8
    Par défaut [resolu] executer cmd linux en Java
    Bonjour,

    J'essaie d'executer la commande linux suivante en Java:
    "
    ffmpeg -i test3.wmv 2>&1 | grep "Duration" | cut -d ' ' -f 4 |sed s/,//
    "
    Si j'execute que le début (avant le |) avec un processbuilder, je n'ai aucun problème. Par contre, au '|', il me met comme erreur:
    "Unable to find a suitable output format for '|'.
    Je sens bien que le problème est le pipe mais je ne vois pas comment faire autrement...

    Merci pour votre aide.

    Mon code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     String[] cmdLine = ["ffmpeg","-i",fOriginal.path,"'|'","grep","'Duration'","|","cut","-d","\' \'","-f","4","|","sed s/,// "]
     
    			ProcessBuilder pb = new ProcessBuilder(cmdLine)
    			pb.redirectErrorStream(true)		
    			Process p = null;
     
    			try
    			{
    				p = pb.start();
    				logProcessOutputAndErrors(p);
    			}
    			catch (Exception ex) 
    			{
    				logger.warn "Can't create process to convert '${inFileName}'"
    				p?.destroy();
    				return false;
    			}
     
    			// wait until the process is finished
    			try
    			{
    				p.waitFor();
    			}
    			catch (InterruptedException e)
    			{
    				p.destroy();
    			}
    			if (p.exitValue() != 0)
    			{
    				logger.warn("Error while converting '" + inFileName + "'.");
    				return false;
    			}

  2. #2
    Membre émérite Avatar de herch
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    655
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2006
    Messages : 655
    Par défaut
    salut,
    juste une idée comme ça, pourquoi ne pas utiliser un process pour chaque commande, par exp tu exécutes ffmpeg -i test3.wmv, puis tu récupères la sortie de la cmd
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    StringBuffer sortie = new StringBuffer();
    BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
    String ligne;
    while ((ligne = reader.readLine) != null)
        sortie.append(ligne);
    et puis tu crée un autre process pour la commande grep et tu lui passes la chaine de sortie récupéré, et ainsi de suite

  3. #3
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,



    Runtime.exec() se contente seulement de lancer un programme avec des arguments, mais n'interprète en aucun cas une ligne de commande. Donc tout ce qui est pipe, redirection variable d'environnement est passé au programme comme un simple argument.

    Sur une ligne de commande cela est interprété par le shell

    Donc ici tu n'as pas 4 programmes mais un seul (ffmpeg) qui reçoit tout le reste comme arguments...



    Concernant ton code j'aurais quelque conseils :
    • Fermes le flux d'entré puisque tu ne l'utilise pas (on ne sait jamais cela pourrait causer un dead-lock).
    • Utilises un seul try/catch qui englobe tout le traitement : c'est plus clair et cela évites de multiplier les traitements
    • Utilises un try/finally pour appeller destroy quoi qu'il arrive.


    Par exemple cela pourrait donner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    	try {
    		ProcessBuilder pb = new ProcessBuilder(cmdLine);
    		pb.redirectErrorStream(true);	
    		Process p = pb.start();
    		try {
    			// On ferme le flux d'entrée du programme (inutilisé)
    			p.getOutputStream().close();
     
    			// On traite le flux de sortie standard (et d'erreur puisqu'il est redirigé)
    			logProcessOutputAndErrors(p);
     
    			// Et on attend la fin du process :
    			p.waitFor();
     
    			// Code retour :
    			if (p.exitValue() != 0) {
    				throw new IOException("Bad Exit Code");
    			}
    			return true;
    		} finally {
    			// Dans tout les cas on détruit le process :
    			p.destroy();
    		}
    	} catch (IOException e) {
    		logger.warn(...)
    		return false;
    	}

    Pour résoudre ton problème tu as deux solutions :
    • Empiler les process en redirigeant les flux de l'un vers l'autre (lire la sortie d'un process, et l'écrire dans le suivant) mais c'est lourdingue...
    • Utiliser le shell système, et lui passer la totalité de la ligne de commande en paramètres. Il se chargera de l'interpréter correctement. Par exemple :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      	// Sous Windows 9x/ME
      	new ProcessBuilder("command.com", "/C", "ligne de commande");
       
      	// Sous Windows NT/2000/XP/Vista :
      	new ProcessBuilder("cmd.exe", "/C", "ligne de commande");
       
      	// Sous les systèmes Unixes :
      	new ProcessBuilder("/bin/sh", "-c", "ligne de commande");
      (en respectant bien sûr tout ce qui a été dis précédemment sur les flux et autres )


    Plus d'info :



    a++

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8
    Par défaut Merci beaucoup
    Merci beaucoup pour votre aide. J'ai utilisé le shell et la librairie adiGuba. Ca marche parfaitement et j'ai gagné beaucoup de temps!!
    Merci encore...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Runtime] executer une ligne de commande cmd à partir de java
    Par mazizou dans le forum API standards et tierces
    Réponses: 13
    Dernier message: 10/05/2007, 13h47
  2. [debutant] execution d'un programme java sous DOS
    Par rika dans le forum Langage
    Réponses: 13
    Dernier message: 26/10/2005, 18h27
  3. [débutant]lancement d'une commande Unix ou LInux depuis Java
    Par msiramy dans le forum API standards et tierces
    Réponses: 6
    Dernier message: 30/09/2005, 18h10
  4. [INFO]Signaux Linux et Java
    Par el3gans dans le forum Général Java
    Réponses: 5
    Dernier message: 26/11/2004, 00h17
  5. executer CMD a distance
    Par Massinissan dans le forum Scripts/Batch
    Réponses: 15
    Dernier message: 28/10/2004, 17h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo