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

Java Discussion :

[Systeme] Process marche sous windows, pas sous linux


Sujet :

Java

  1. #1
    Nouveau membre du Club
    Inscrit en
    Mai 2004
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 65
    Points : 33
    Points
    33
    Par défaut [Systeme] Process marche sous windows, pas sous linux
    Bonjour,

    J'utilise un Process pour lancer un script perl.
    J'ai testé avec succès cette partie de code sous windows.

    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
    try{
    String commands = new String("perl + repertoireCourant.getAbsolutePath() + File.separator + "fichiers" + File.separator + "script.pl" + " " + "\"" + f + "\" " +
    classe.getMethode1() + " " +
    classe.getMethode2() + " " +
    classe.getMethode3() + " " +
    classe.getMethode4()
    );
     
    Process process = Runtime.getRuntime().exec(commands);
     
    //  Attendre la fin
    process.waitFor(); 
     
    BufferedReader r = new BufferedReader(new InputStreamReader(process.getInputStream()));
     
    System.out.println("commande = " + commands);
    String resultat = new String(r.readLine());
    do { 
          textAreaConcole.append(" $ " + resultat + "\n");	
          resultat = r.readLine();
    } while (resultat != null);
     
    }
     
    catch (IOException e) {
            textAreaConcole.append("Erreur lors du lancement\n");
            e.printStackTrace();
    }
    seulement, sous linux, le script ne se lance pas. Pourtant quand je tape la commande passé en paramétre, elle fonctionne.
    Ce script créer un fichier. Je me demande si ce n'est pas un problème de droit en écriture.
    J'ai cherché longtemps et je ne trouve pas d'explications.

    Merci d'avance pour vos réponses.

  2. #2
    Nouveau membre du Club
    Inscrit en
    Mai 2004
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 65
    Points : 33
    Points
    33
    Par défaut
    Il n'y a pas d'erreur d'execution, ca ne rentre pas dans le catch.
    La commande ne fait rien : pas de temps d'execution ni de fichiers produit.
    J'ai affiché le retour avec exitValue() qui est égale à 2 !?

  3. #3
    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,

    Citation Envoyé par Zapan
    J'ai affiché le retour avec exitValue() qui est égale à 2 !?
    Il y a de forte chance que le programme appellé (perl) ai produit une erreur...
    Il faudrait donc que tu affiches sa sortie d'erreur (getErrorStream()) pour voir le message qu'il t'affiche...

    En général il est toujours conseillé de lire les deux flux au complet et dans deux threads séparé afin d'éviter les blocages...

    a++

  4. #4
    Nouveau membre du Club
    Inscrit en
    Mai 2004
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 65
    Points : 33
    Points
    33
    Par défaut
    Oui je viend d'essayer getErrorStream.

    Quand je fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    String commands = new String("perl + repertoireCourant.getAbsolutePath() + File.separator + "fichiers" + File.separator + "fichiers"" + " " + "\"" + stringS + "\" " +
    "\"\" " +
    "\""  + classe.getMethode1() + "\" " +
    "\""  + classe.getMethode2() + "\" " +
    "\""  + classe.getMethode3() + "\" " +
    "\""  + classe.getMethode4() + "\""
    );
    J'obtiens la commande
    perl rep/fichiers/perl.pl "adf" "" "45" "456" "43" "416"
    qui marche dans le terminal.
    Mais quand je la lance dans Process, le parametre "" est mal interprete par le script perl ce qui le fait s'arreter (die). Je ne sais pas quoi faire pour que ce parametre soit passé correctement.
    Le script perl vérifie que :
    Lancer en ligne de commande, c'est verifier,
    Lancer depuis Process, c'est pas vérifier... !?

  5. #5
    Membre habitué

    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2002
    Messages : 125
    Points : 150
    Points
    150
    Par défaut
    il existe une version de exec qui prend en parametre la ligne de commande ET les parametres, tu devrais l'essayer.
    ne ré-inventez pas la roue, allez chercher dans les Commons de Jakarta

  6. #6
    Nouveau membre du Club
    Inscrit en
    Mai 2004
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 65
    Points : 33
    Points
    33
    Par défaut
    J'ai essayer avec des ', ca ne change rien.
    J'ai ajouter un print :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    print "2eme_param=$2eme_param\n";
    if($2eme_param eq "")
    En ligne de commande j'obtient pour résultat :
    2eme_param=
    fichier created.
    Ok.

    Dans le proccess j'obtient :
    Error: Unable to read ""
    2eme_param=""

    Comment faire pour passer un argument vide ?

  7. #7
    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
    Il s'agit d'une différence de comportement des shells windows et Unix/Linux...

    Lorsque tu tapes la commande suivante dans un Shell Windows :
    perl rep/fichiers/perl.pl "adf" "" "45" "456" "43" "416"
    Le programme perl les recois tel quel, et "enlève" lui-même les quotes autour des paramètres... (Le Shell Windows n'effectue quasiment aucune modification sur la ligne de commande saisie).


    Sous Unix/Linux, les quotes sont interprété par le shell, et sont supprimé avant l'appel du programme (tout comme beaucoups d'autre caractères spéciaux qui sont interprété d'une manière ou d'une autre). Ce dernier recoit donc les paramètres sans quotes, et la version Unix/Linux de perl ne supprime pas ces quotes.


    Mais la commande exec() de Java n'utilise pas le Shell mais lance le programme directement
    Et donc lorsqu'il interpète la ligne de commande tu obtiens des erreurs...


    Citation Envoyé par jcarre
    il existe une version de exec qui prend en parametre la ligne de commande ET les parametres, tu devrais l'essayer.
    +1

    Je te conseille de créer toi-même le tableau des paramètres pour être sûr de ce que tu passes à ton application :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    String[] commands = new String[7];
    commands[0] = "perl";
    commands[1] = repertoireCourant.getAbsolutePath() + File.separator + "fichiers" + File.separator + "fichiers"";
    commands[2] = stringS;
    commands[3] = classe.getMethode1();
    commands[4] = classe.getMethode2();
    commands[5] = classe.getMethode3();
    commands[6] = classe.getMethode4();
     
    // ...


    Derniere remarques : il faut toujours lire les flux de sortie de ton programme (avec getInputStream() et getErrorStream()), et surtout avant de faire un waitFor(). Et de préférence dans deux threads parallèles.

    Explication : La JVM utilise deux (petit) buffer pour lire la sortie stdout et stderr du programme appellé, mais lorsque ces buffers sont plein, le programme appellé reste bloqué sur la méthode d'écriture tant que le buffer de la JVM n'est pas vidé.

    Mais si de ton coté ne lit pas les flux de ton Process (ou que tu fait un waitFor() avant), les deux programmes se retrouve bloqué l'un autre...


    a++

    PS : si tu utilises Java 5.0 tu peux utiliser la classe ProcessBuilder pour créer et exécuter ton programme perl, de plus elle permet de regrouper les flux stdout et stdin en un seul flux en utilisant la méthode redirectErrorStream(true) avant de démarrer le process...

  8. #8
    Membre chevronné
    Homme Profil pro
    Dév. Java & C#
    Inscrit en
    Octobre 2002
    Messages
    1 414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Dév. Java & C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 414
    Points : 1 996
    Points
    1 996
    Par défaut
    Essaie d'appeler la méthode exec(String, String[])

    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
     
    try{
    String commands = new String("perl + repertoireCourant.getAbsolutePath() + File.separator + "fichiers" + File.separator + "script.pl");
     
    String[] arguments = {f,
                                     classe.getMethode1(), 
                                     classe.getMethode2(),
                                     classe.getMethode3(),
                                     classe.getMethode4()
                                    };
     
     
    Process process = Runtime.getRuntime().exec(command, arguments);
     
    //  Attendre la fin
    process.waitFor();
     
    BufferedReader r = new BufferedReader(new InputStreamReader(process.getInputStream()));
     
    System.out.println("commande = " + commands);
    String resultat = new String(r.readLine());
    do {
          textAreaConcole.append(" $ " + resultat + "\n");   
          resultat = r.readLine();
    } while (resultat != null);
     
    }
     
    catch (IOException e) {
            textAreaConcole.append("Erreur lors du lancement\n");
            e.printStackTrace();
    }
    Bien le bonjour chez vous
    Jowo

  9. #9
    Membre chevronné
    Homme Profil pro
    Dév. Java & C#
    Inscrit en
    Octobre 2002
    Messages
    1 414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Dév. Java & C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 414
    Points : 1 996
    Points
    1 996
    Par défaut
    adiGouba m'a soufflé la politesse.

    Suit les conseils d'adiGouba et tu verras que ton programme fonctionnera.

    Exmple pour t'inspirer:

    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
     
    import java.io.BufferedInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.StringBufferInputStream;
    import java.io.StringReader;
     
    /*
     * Created on 13.09.2005
     *
     * To change the template for this generated file go to
     * Window>Preferences>Java>Code Generation>Code and Comments
     */
     
    /**
     * @author marfab001
     * 
     * To change the template for this generated type comment go to
     * Window>Preferences>Java>Code Generation>Code and Comments
     */
    public class TestProcess {
     
        private Runtime runtime;
        private Process process = null;
        private InputStream input = null; 
        private OutputStream output = null;
        private OutputStream error = null;
        private long timeout = 0;
     
        public TestProcess() {
           runtime = Runtime.getRuntime();
        }
     
        public int execute(String[] args) throws IOException {
            int status = -1;
     
            /* Creation du sous-processus */ 
            process = runtime.exec(args, null, null);
     
        	/* Consomme la sortie d'erreur */
            createProdConsThread(process.getErrorStream(), error, 1024).start();
     
            /* Consomme la sortie standard */
            createProdConsThread(process.getInputStream(), output, 1024).start();
     
            if (input != null) {
            	/* Fournit les données à l'entrée standard */
            	createProdConsThread(input, process.getOutputStream(), 1024).start();
            }
     
            /*  */
            if (timeout > 0L) {
                Thread subProcess = createSubProcess(process);
                subProcess.start();
     
                try {
                	subProcess.join(timeout);
                	try {
                		status = process.exitValue();
                	}
                	catch (IllegalThreadStateException itse) {
                		process.destroy();
                		status = process.exitValue();
                	}
                }
                catch (InterruptedException ie) {
                	ie.printStackTrace();
                }
            }
            /* On attend que le sous-processus se termine */
            else if (timeout == 0L) {
                try {
    				status = process.waitFor();
    			}
                catch (InterruptedException ie) {
    				// TODO Auto-generated catch block
    				ie.printStackTrace();
    			}
            }
     
            return status;
        }
     
        /**
             * @return Returns the error.
             */
    	public OutputStream getError() {
    		return error;
    	}
     
        /**
             * @param error The error to set.
             */
    	public void setError(OutputStream errStream) {
    		this.error = errStream;
    	}
     
        /**
             * @return Returns the input.
             */
    	public InputStream getInput() {
    		return input;
    	}
     
        /**
             * @param input The input to set.
             */
    	public void setInput(InputStream inpStream) {
    		this.input = inpStream;
    	}
     
        /**
             * @return Returns the output.
             */
    	public OutputStream getOutput() {
    		return output;
    	}
     
        /**
             * @param output The output to set.
             */
    	public void setOutput(OutputStream outStream) {
    		this.output = outStream;
    	}
     
        /**
             * @return Returns the timeout.
             */
    	public long getTimeout() {
    		return timeout;
    	}
     
        /**
             * @param timeout The timeout to set.
             */
    	public void setTimeout(long timeout) {
    		this.timeout = timeout;
    	}
     
        private Thread createProdConsThread(final InputStream input,
                                            final OutputStream output,
                                            final int bufferSize) {
            Thread thread = new Thread() {
                public void run() {
                    try {
                        BufferedInputStream outStreamProcess =
                            new BufferedInputStream(input);
                        byte[] buffer = new byte[bufferSize];
                        int read;
     
                        while ((read = outStreamProcess.read(buffer, 0, buffer.length)) != -1) {
                            if (output != null) {
                                output.write(buffer, 0, read);
                            }
                        }
                        outStreamProcess.close();
                    }
                    catch (IOException ioe) {
                        // TODO Auto-generated catch block
                        ioe.printStackTrace();
                    }
                }
            };
            return thread;
        }
     
        private Thread createSubProcess(final Process process) {
            return new Thread() {
            	public void run() {
                    try {
                        process.waitFor();
                    }
                    catch(InterruptedException ie) {
                        ie.printStackTrace();
                    }
                }
            };
        }
     
    	public static void main(String[] args) throws Exception{
    		String[] cmd = {"cmd", "/c",
                            "dir", "C:\\Programme\\Mozilla Firefox",
                            ">", "c:\\Programme\\Mozilla Firefox\\dirout.txt"};
     
            TestProcess process = new TestProcess();
            /*
            process.setInput(new FileInputStream("source.txt"));
            process.setOutput(new FileOutputStream("dest.txt"));
            process.setError(new FileOutputStream("error.log"));
            */
            process.setTimeout(0L);
     
            int status = -1;
    		try {
    			status = process.execute(cmd) ;
     
    			System.out.println("La commande retourne : " + status);
     
    		} catch (IOException ioe) {
    			// TODO Auto-generated catch block
    			ioe.printStackTrace();
    		}
     
            System.exit(status);
    	}
    }
    Bien le bonjour chez vous
    Jowo

  10. #10
    Nouveau membre du Club
    Inscrit en
    Mai 2004
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 65
    Points : 33
    Points
    33
    Par défaut
    Merci pour vos réponses. Je suis entrain de faire de nouveau tests.
    Ce bout de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    BufferedReader r = new BufferedReader(new InputStreamReader(process.getInputStream()));
     
    String resultat = new String(r.readLine()); -> exception
    do {
          textAreaConcole.append(" $ " + resultat + "\n");   
          resultat = r.readLine();
    } while (resultat != null);
    process.waitFor();
    n'est pas très bon, car si il n'y a pas de InputStream, ca créer une exception.
    Quelle est la solution le plus propre : le mettre dans un try ... catch, ou verifier que r contient quelque chose, mais je n'ai pas trouvé comment faire.

  11. #11
    Nouveau membre du Club
    Inscrit en
    Mai 2004
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 65
    Points : 33
    Points
    33
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    String[] commands = new String[7];
    commands[0] = "perl";
    commands[1] = repertoireCourant.getAbsolutePath() + File.separator + "fichiers" + File.separator + "fichiers"";
    commands[2] = stringS;
    commands[3] = classe.getMethode1();
    commands[4] = classe.getMethode2();
    commands[5] = classe.getMethode3();
    commands[6] = classe.getMethode4();
    Marche sous linux !

  12. #12
    Nouveau membre du Club
    Inscrit en
    Mai 2004
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 65
    Points : 33
    Points
    33
    Par défaut
    Ca marche sous linux quand stringS = new String("");
    et pas quand stringS = new String("\"\"");

    Ca marche sous windows quand stringS = new String("\"\"");
    et pas quand stringS = new String("");

    C'est déjà bien que j'ai réussi à faire marcher sous linux, mais c'est pas top pour l'interopabilité !

  13. #13
    Nouveau membre du Club
    Inscrit en
    Mai 2004
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 65
    Points : 33
    Points
    33
    Par défaut
    J'ai fais une méthode générique :
    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
    33
    34
    35
    36
    private void executeCommande(String[] commande, int error) {
     
        //System.out.println("commande = " + commandsTraderCreator);
        try{
     
        	Process process1 = Runtime.getRuntime().exec(commande);
     
        	BufferedReader bufferedReaderInputStream = new BufferedReader(new InputStreamReader(process1.getInputStream()));
     
        	BufferedReader bufferedReaderErrorStream = new BufferedReader(new InputStreamReader(process1.getErrorStream()));
     
        	String resultat = new String(bufferedReaderInputStream.readLine());
        	do { 
        	        textArea.append(" $ " + resultat + "\n");	
        		resultat = bufferedReaderInputStream.readLine();
        	} while (resultat != null);
     
        	resultat = new String(bufferedReaderErrorStream.readLine());
        	do { 
        		textArea.append(" $ " + resultat + "\n");	
        		resultat = bufferedReaderErrorStream.readLine();
        	} while (resultat != null);
     
        	// Attendre la fin
        	process1.waitFor(); 
     
        	error = process1.exitValue();
        }
        catch (Exception e2) {
        	error = -1;
        	System.out.println("Erreur lors du lancement du script perl.\n" + e2);
        	e2.printStackTrace();
        }
     
        System.out.println("Valeur de retour = " + error);
    }
    Les méthodes sont bien appellée dans le bon ordre ?
    J'ai toujours le même problème : si il n'y a pas de InputStream ou de ErrorStream, ca créer une exception. J'ai regarder How to Use File Streams sans succès.

Discussions similaires

  1. souris + clavier ne marche pas sous windows xp
    Par guitou_429 dans le forum Windows XP
    Réponses: 23
    Dernier message: 02/12/2010, 12h06
  2. Script qui marche sous Linux mais pas sous Windows et vice versa
    Par tu-phat dans le forum Applications et environnements graphiques
    Réponses: 2
    Dernier message: 26/11/2009, 02h39
  3. Ligne tronquée sous unix, pas sous windows
    Par dude666 dans le forum AIX
    Réponses: 3
    Dernier message: 27/05/2009, 16h21
  4. Réponses: 1
    Dernier message: 23/04/2008, 17h23
  5. Aero ne marche pas sous windows vista ultimat
    Par eminemanaas1985 dans le forum Windows Vista
    Réponses: 4
    Dernier message: 16/04/2008, 23h53

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