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 :

Exécuter un script, redirection entrée-sortie


Sujet :

Langage Java

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2007
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 22
    Points : 18
    Points
    18
    Par défaut Exécuter un script, redirection entrée-sortie
    Je ne comprends pas réellement comment exécuter un commande unix depuis une méthode java

    En effet, je n'arrive pas à rediriger vers un nouveau fichier le résultat de la commande unix utilisée

    Par exemple, si je veux utiliser la commander "ls", voici mon code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public void lsBis(String monRepertoire) {
        String cmd = "ls /"+ monRepertoire + " > /repertoireDeSauvegarde/ls.toto";
        // Execution de la commande ls
        try {
            Runtime r = Runtime.getRuntime();
            Process p = r.exec(cmd);
        } catch (IOException e) {
            System.out.println("Erreur lors de l'execution de la commande cp");
            e.printStackTrace();
        }
    }
    Ceci ne crée pas de fichier "ls.toto"

    Je peux m'amuser à créer un fichier avec du code java, le code se transforme alors en:

    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
    ...
        //Création du fichier temporaire dans lequel sera stocké l'arborescence
        File lsFile = new File(repertoireDeSauvegarde,"ls.toto");
        try {
            lsFile.createNewFile();
        } catch (IOException e1) {
            System.out.println("Erreur lors de la création du fichier");
            e1.printStackTrace();
        }
     
        // Execution de la commande ls
        ...
     
        // Ecriture dans le fichier créé
        try {
            FileOutputStream fos = new FileOutputStream(lsFile);
    	int c;
    	while ((c = in.read()) != -1) {
                // Ecriture dans le fichier temporaire
                fos.write(c);
    	}
    	in.close();
    	fos.close();
        } catch (FileNotFoundException e1){
            System.out.println("Fichier non trouvé");
            e1.printStackTrace();
        }
    ...
    Superbe tout semble fonctionner
    Cependant, pour l'écriture d'un gros fichier, l'exécution du programme prend vraiment du temps.
    De plus je dois ensuite manipuler ce fichier comme lui enlever une ligne (avec la commande sed par exemple) et je suis donc obligé de repasser par la création de fichier depuis du code java. Il devient donc très contraignant (en plus de ralentir fortement le programme) de manipuler un fichier sans pouvoir utiliser la redirection ">"


    J'ai donc voulu créer un petit script "ls.sh" exécutant tout bêtement "ls /monRepertoire > /repertoireSauvegarde/ls.toto"
    Ce script fonctionne très bien si je le lance manuellement, mais il ne fait rien du tout s'il est exécuté depuis la méthode Java

    En espérant avoir été assez clair, je vous remercie d'avance

    PS: Oui je sais, utiliser des commandes unix via du java c'est mal xD
    rePS: je précise que le but de mon appli n'est pas d'utiliser la seule commande "ls", mais qu'elle utilise également un script "maison" que je ne peut transcrire en java

  2. #2
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Les "instructions" < >, etc. sont géré par le shell ! Or Java lance les programmes directement sans utiliser le shell. Ainsi le > est passé en paramètre au ls, c'est donc comme si tu tapais dans le shell la ligne suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ls /monRepertoire ">" /repertoireDeSauvegarde/ls.toto
    (notes bien les quotes autour de > pour le "protéger")

    Ensuite j'ai plusieurs remarques :
    • Ton code possède plusieurs bloc try/catch : or tu ne devrais n'en avoir qu'un seul qui englobe tout le traitement (si tu n'arrives pas à créer le fichier, cela ne sert à rien d'écrire dedans...)
    • Tu devrais utiliser des bloc try/finally pour les fermetures des flux...
    • Toutes les entrées/sorties du Process (in, out et err) doivent être soit traité (dans des threads différents), soit fermé. Sinon tu as de forte chance de bloquer le process...



    Pour plus de détail, je te conseille de jeter un coup d'oeil sur ce sujet : Runtime.exec() n'est pas des plus simple...

    Tu y trouveras plus de détail sur cela, ainsi qu'une librairie (compatible Java 5.0) permettant d'utiliser directement (et simplement) des commandes du shell système...

    a++

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2007
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 22
    Points : 18
    Points
    18
    Par défaut
    Malheureusement, mon EDI (Java Studio Creator) semble ne pas pouvoir supporter Java 5.0 (et apres un petit parcours des sources moi non plus xD)

    J'ai pas tellement envie de me lancer dans la manipulation de threads pour le moment, je vais donc voir si je m'aventurerai dans cette voie

    Merci pour ces conseils et ces explications.


    EDIT: aurtaugraff

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2007
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 22
    Points : 18
    Points
    18
    Par défaut
    Il me vient une idée

    Et si je m'amuse à implemeter des programmes (en C par exemple) réalisant les appels des fonctions "ls" et cie (créant, manipulant des fichiers)
    En appelant ces nouvelles "commandes" depuis mon appli Java, ceci peut il fonctionner (où comprends-je rien de rien)?

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2007
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 22
    Points : 18
    Points
    18
    Par défaut
    J'ai trouvé une page bien intéressante :
    http://java.sun.com/developer/JDCTec...03/tt0304.html

    Il existe donc bien en Java une façon d'invoquer un shell et d'utiliser les redirections entrée-sortie très simplement

    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
    import java.io.IOException;
     
    public class ExecDemo2 {
     
        static void doExec() throws IOException {
     
            // invoke a shell and give command to it
     
            Runtime runtime = Runtime.getRuntime();
            String[] args = new String[]{"sh", "-c", "ls | wc >out2"};
     
            Process p = runtime.exec(args);
        }
     
        public static void main(String[] args) throws IOException {
            doExec();
        }
    }
    Ceci fonctionne parfaitement, inutile alors de se compliquer la vie avec des threads


    PS: dsl pour le triple message

  6. #6
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par darkrio
    Ceci fonctionne parfaitement, inutile alors de se compliquer la vie avec des threads
    Ca fonctionne dans ce cas simple...


    Mais comme tu ne lis pas les flux de sortie, si la commande lancé écrit dans le flux de sortie d'erreur le process risque de se bloquer (blocage IO).

    Dans ce cas il faudrait au moins fermer les flux pour éviter ce blocage (mais le message d'erreur serait perdu. De plus il serait peut-être préférable d'attendre la fin du process avant de continuer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
            Runtime runtime = Runtime.getRuntime();
            String[] args = new String[]{"sh", "-c", "ls | wc >out2"};
     
            Process p = runtime.exec(args);
    	p.getOutputStream().close();
    	p.getInputStream().close();
    	p.getErrorStream().close();
    	p.waitFor();
    Maintenant, si tu veux récupérer la sortie de la commande, il est surement préférable de la récupérer en direct plutôt que de la rediriger vers un fichier pour la lire ensuite...

    Pour plus de détail tu peux jeter un coup d'oeil à ce tutoriel : Exécuter une application externe en Java


    Enfin, si tu ne veux pas t'embêter avec les threads tu peux utiliser ma librairie cité plus haut (Runtime.exec() n'est pas des plus simple...) qui permet de simplifier cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    // Executes la commande avec le shell système
    // en renvoyant les sorties vers les sorties standard Java
    // (System.out et System.err)
    System.shell("ls | wc >out2");
    a++

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2007
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 22
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par adiGuba
    Pour plus de détail tu peux jeter un coup d'oeil à ce tutoriel : Exécuter une application externe en Java
    Non je ne peux pas, mon EDI est incompatible avec Java 5.0

    En tout cas merci pour tes explications

  8. #8
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par darkrio
    Non je ne peux pas, mon EDI est incompatible avec Java 5.0
    Heu... Ce tutoriel parle de Runtime.exec() et ne concerne pas Java 5.0 en particulier...

    a++

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2007
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 22
    Points : 18
    Points
    18
    Par défaut
    J'ai mis une mauvaise citation
    Citation Envoyé par adiGuba
    Enfin, si tu ne veux pas t'embêter avec les threads tu peux utiliser ma librairie cité plus haut (Runtime.exec() n'est pas des plus simple...)
    A ce propos, c'est fort dommage d'ailleurs qu'il soit si difficile d'acceder aux "sujets intéressants" des blogs.

  10. #10
    Membre chevronné
    Avatar de Clorish
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 474
    Points : 2 158
    Points
    2 158
    Par défaut
    utilise plutot le bouton en bas que la modification du titre
    On passe du temps a vous repondre, alors soyez sympas, passez du temps ..... a vous relire !
    --
    Pourquoi tant de haine pour cette pauvre aide Delphi ????
    Aiiimezzz laaaaa .... Si-Non-Cham-Pi-Gnon !!!
    --
    Pour plus de Renseignements : Venez me rejoindre sur Msn .... Promis je mords pas

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

Discussions similaires

  1. [tcsh] Redirection entrée/sortie standards
    Par arkham55 dans le forum Shell et commandes POSIX
    Réponses: 5
    Dernier message: 27/04/2012, 09h21
  2. Redirection des entrées/sorties du process (ping)
    Par ero-sennin dans le forum Langage
    Réponses: 29
    Dernier message: 18/11/2008, 18h01
  3. Réponses: 9
    Dernier message: 18/07/2007, 12h04
  4. redirection entrée/sortie sous windows en C
    Par alexlecool dans le forum C
    Réponses: 3
    Dernier message: 08/12/2006, 09h05
  5. redirection entrée sortie
    Par ludovik dans le forum Réseau
    Réponses: 4
    Dernier message: 20/06/2006, 20h28

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