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 :

Erreur lors de l'exécution d'une commande shell


Sujet :

Langage Java

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2011
    Messages
    192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2011
    Messages : 192
    Points : 107
    Points
    107
    Par défaut Erreur lors de l'exécution d'une commande shell
    Bonjour,

    J'ai un petit problème assez récurrent dans mon application...
    Je dois effectuer des commandes shell, à savoir un mount et un umount. (j'ai également dû faire des iptables dans un autre projet mais j'ai contourné le problème).

    Voici ma méthode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    cmdShell = "mount " + ligne + " " + cheminDisque;	
    try{
    	p = Runtime.getRuntime().exec(cmdShell);		
    }catch(IOException e){
    	Logger.getLogger().error("Erreur lors du montage d'une partition de disque");
    }
    Mon problème, c'est que de temps en temps, les commandes shell ne sont pas exécutée. Le code est bien exécuté comme il faut, mais la commande n'a aucun effet.

    Il ne s'agit pas d'une erreur dans la commande ou autre, puisque lancée plusieurs fois, la commande s'exécute. Je suis donc obligé de faire une boucle pour vérifier la presence ou non de données dans le repertoire ce qui me permet de savoir si le disque est monté. Tant que la commande n'a pas été approuvée, on boucle.

    voici un exemple de resultat :

    mount /dev/sda1 /media/disqueRecup/
    on demonte
    on demonte
    on demonte
    on demonte
    mount /dev/sda3 /media/disqueRecup/
    on demonte
    mount /dev/sdb1 /media/disqueRecup/
    disque trouve

    on peut voir que le mount se fait à chaque fois, (ce qui n'est pas toujours le cas) mais que les umount ne passe pas tout le temps.. pour le premier mount, il n'y a pas moins de 4 tentatives pour que la commande umount passe...

    J'obtiens le résultat que je veux avec ma boucle (technique que j'ai utilisé pour le iptables dans un autre projet) mais je trouve ça vraiment crade de devoir réitérer la commande jusqu'à ce qu'elle fonctionne...

    Y a t-il une autre méthode pour exécuter du shell ? Y a-t-il quelqu'un qui sait pourquoi ce phénomène se produit ?

    N'hésitez pas si vous avez la moindre informations, car cette erreur est totalement illogique à mes yeux !

    Merci beaucoup

  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,



    Si ton code se limite à cela c'est normal (enfin si on peut dire).

    • Il est préférable de séparer les paramètres de la commande. Au passage depuis Java 5 on privilégiera ProcessBuilder aux méthodes Runtime.exec()...
    • Il faut toujours traiter les flux d'entré/sorties, ou alors les fermer pour éviter les deadlock. Au passage si tu as des problèmes il est préférable de lire le flux de sortie/d'erreurs pour voir s'il n'y a pas de problème (avec Processbuilder tu peux les regrouper c'est plus simple).
    • Le process peut mettre un "certain temps" à se lancer et s'exécuter. Il est donc préférable d'attendre qu'il soit fini (surtout dans ton cas).
    • A noter qu'en règle général les commandes unix utilise leurs code retour pour indiquer leurs déroulement. En règle général un code de retour qui vaut 0 indique un bon fonctionnement...




    Perso je remplacerais ton code par celui-ci :
    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
    	// On crée le process via un ProcessBuilder :
    	Process process = new ProcessBuilder("mount", ligne, cheminDisque).start();
    	try {
    		// On ferme les flux (puisqu'on ne les utilises pas)
    		process.getOutputStream().close();
    		process.getErrorStream().close();
    		process.getInputStream().close();
     
    		// On attend la fin du process :
    		int result = process.waitFor();
     
    	} finally {
    		// On détruit le process (garde-fou en cas de problème)
    		process.destroy();
    	}

    Ou si tu veux lire le flux de sortie standard et d'erreur :
    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
    	// On crée le process via un ProcessBuilder :
    	Process process = new ProcessBuilder("mount", ligne, cheminDisque)
    		.redirectErrorStream(true) // on redirige stderr dans stdout
    		.start();
    	try {
    		// On ferme les flux (puisqu'on ne les utilises pas)
    		process.getOutputStream().close();
    		process.getErrorStream().close();
     
    		// On lit le flux de sortie standard
    		// et on le recopie dans la sortie standard :
    		InputStream input = process.getInputStream();
    		try {
    			byte[] buf = new byte[8192];
    			int len;
    			while ( (len=input.read(buf)) >= 0 )
    				System.out.write(buf, 0, len);
    		} finally {
    			input.close();
    		}
     
    		// On attend la fin du process :
    		int result = process.waitFor();
     
    	} finally {
    		// On détruit le process (garde-fou en cas de problème)
    		process.destroy();
    	}

    a++

  3. #3
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2011
    Messages
    192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2011
    Messages : 192
    Points : 107
    Points
    107
    Par défaut
    je te remercie de ta réponse !

    Je venais de passer sur des posts que tu avais déjà écrits ailleurs sur le site !
    je ne connaissais pas cette méthode, et google renvoie quasiment tout le temps sur le runtime.exec..

    Alors je viens de tester, et j'obtiens le même problème... sauf que cette fois, je peux voir le résultat de la commande grâce à

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int result = process.waitFor();
    est ce normal que le umount ne se fasse pas systématiquement ? J'ai déjà été confronté à ce problème et sur google personne n'a l'air d'avoir le même... peut être que ça vient de ma machine..

    je garde cette méthode, puisque cette fois je peux boucler tant que le retour n'est pas égal à 0.

    je vais regarder a quoi correspondent les codes d'erreur (8 et 1 pour le moment).

    merci beaucoup !

    Sinon, si quelqu'un a déjà eu ce problème, la commande qui doit etre rappelé plusieurs fois car elle n'est pas toujours executée, qu'il me fasse signe !

  4. #4
    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
    La commande est bien exécuté... mais elle échoue pour une raison ou une autre.
    As-tu essayer d'afficher la sortie de la commande pour voir s'il n'y avait pas un message d'erreur indiquant les raisons de cela ?


    Sinon waitFor() c'est dans Process


    a++

  5. #5
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2011
    Messages
    192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2011
    Messages : 192
    Points : 107
    Points
    107
    Par défaut
    rha ! pas eu le temps de supprimer mon post à temps !

    je vais tester la sortie, voir s'il n'y a pas un message d'erreur, mais je ne récupérais rien en faisant cette manipulation avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Runtime.getRuntime().exec(cmdShell);
    je vais faire le test.

    merci pour tes explications

  6. #6
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2011
    Messages
    192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2011
    Messages : 192
    Points : 107
    Points
    107
    Par défaut
    pas de sortie , rien du tout...

    le plus bizzare c'est que en lançant le programme plusieurs fois, parfois la commande passe du premier coup, parfois du second, du troisieme...

    peut etre y a-t-il un rapport avec le type de commande lancée ;
    le fdisk -l fonctionne toujours du 1er coup,
    le mount aussi a en fait l'air de se faire du premier coup
    en revanche, c'est le umount qui pose des soucis.

    j'ai egalement eu des soucis avec iptables sur le même principe.

    mais les codes d'erreur me permettent de réiterer tant que le resultat est different de 0 donc je peux gerer avec ça. Même si je trouve que ça reste sale... Mais peut être que ça vient de l'ordinateur !
    a redire puisque je change carte mère, proc, et que je réinstalle un système !

    merci a toi pour ton temps et tes reponses en tout cas

  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
    Euh... Il faut lire le flux explicitement (comme dans mon second code)


    a++

  8. #8
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    qu'est-ce que te sort umount quand tu rajoute -v dans ses paramètres?

  9. #9
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2011
    Messages
    192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2011
    Messages : 192
    Points : 107
    Points
    107
    Par défaut
    alors j'ai compris le probleme..

    Je testais la sortie avec le inputstream, qui ne renvoie rien du tout puisque umount ned fait pas de renvoi.
    pour voir l'erreur il fallait que j'utilise le errorstream... j'avais pas fait attention à celui-ci et forcement, dans errorStream, il y a error donc...

    @AdiGuba merci beaucoup ton code est nickel ! juste que je prenais l'inputstream au lieu de l'errorStream

    l'erreur affichée est un simple device is busy, mais je ne sais toujours

    @tchize_ avec -v l'erreur est la suivante :
    Broken pipe
    umount: /media/disqueRecup/: not mounted

    pourtant le ount passe bien.

    Entre le moment ou je monte et que je demonte, je fais un petit traitement :
    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
     
    File repFichier = new File(Configuration.getProperty("global.cheminDisqueAmovible"));
    		File[] disqueAmovibles = repFichier.listFiles();
     
    		for (int i=0 ; i<disqueAmovibles.length ; i++){
     
    			File fichierCache = disqueAmovibles[i];
     
    			if (fichierCache.isFile() && fichierCache.getName().equals(Configuration.getProperty("global.fichierCache"))){
    				disqueAmovibles = null;
    				return repFichier;
    			}	
    		}
    		disqueAmovibles = null;
    		repFichier = null;
    et cela genere l'erreur device is busy

    j'ai donc deux solutions, soit je boucle tant que le umount ne passe pas, sinon umount -l, qui "force" le démontage.

    Merci pour vos réponses

  10. #10
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    File ne peux pas empecher le démontage en lui meme car File est un wrapper sur une simple String, il n'a aucune référence préservée vers le filesystem.

    Par contre, tu peux avoir des applis système comme les indexeurs qui tavaillent sur le système de fichier ou avoir des input/output stream ouverts dessus

    Attention que -l fait un lazy umount. Même sir le système n'est plus accessible, ca ne veux pas dire qu'on peux l'éjecter en sécurité

  11. #11
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2011
    Messages
    192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2011
    Messages : 192
    Points : 107
    Points
    107
    Par défaut
    en fait si je commente le code avec les File...
    le mount pase bien en une fois.

    Ce n'est pas vraiment logique car comme tu dis, ça ne devrait pas faire passer le disque en busy..

    pour le -l c'est pas faux, je crois que je vais garder la boucle !

    merci !

  12. #12
    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 tchize_ Voir le message
    File ne peux pas empecher le démontage en lui meme car File est un wrapper sur une simple String, il n'a aucune référence préservée vers le filesystem.
    Il y a quand même un accès aux filesystems lorsque tu utilises certaines méthodes concernant le status du fichier(comme exists(), isFile(), size(), ...)

    Par contre je ne pense pas que ce soit bloquant...


    a++

  13. #13
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2011
    Messages
    192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2011
    Messages : 192
    Points : 107
    Points
    107
    Par défaut
    de toute façon je remet a null dans tous les cas, avant de faire le umount.

    en tout cas merci maintenant je sais pourquoi ca le fait !

    je passe en résolu !

    vous assurez en tout cas !

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 07/10/2009, 11h38
  2. [XL-2003] Erreur lors de l'exécution d'une procédure
    Par pacocnec dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 29/06/2009, 12h39
  3. Erreurs lors de l'exécution d'une procédure
    Par vanesa dans le forum PL/SQL
    Réponses: 2
    Dernier message: 05/01/2009, 17h48
  4. Erreur lors de l'exécution d'une requête avec ADOquery
    Par doolar dans le forum Bases de données
    Réponses: 2
    Dernier message: 03/05/2008, 13h26
  5. [PostgreSQL] [PostGreSQL] Obtention d'une erreur lors de l'exécution d'une requête
    Par cbombabill dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 06/03/2008, 11h56

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