2009-07-03 6 views
3

J'ai eu du code qui a couru des commandes à travers Runtime.getRuntime.exec (String), et cela a fonctionné sur Windows. Quand j'ai déplacé le code vers Linux, il s'est cassé, et la seule façon de le réparer était de passer à la version exec (String []). Si je laisse les choses de cette façon, le code fonctionnera-t-il de la même manière sous Windows et Linux, ou devrais-je utiliser exec (String) sous Windows et exec (String []) sous Linux?Est-ce que java Runtime.exec (String []) est indépendant de la plateforme?

Répondre

4

Utilisez Chaîne [] sur les deux.

La réponse I gave you before était le résultat de plusieurs heures de débogage d'un logiciel de production fonctionnant sous Windows.

Après beaucoup d'efforts que nous (I) est venu à la solution affichée avant (utiliser String [])

Depuis les problèmes que vous avez été sur Linux, je suppose que l'aide du tableau sur les deux seront sois le meilleur.

BTW. J'ai essayé cette méthode avec Java 1.4, Depuis lors une nouvelle classe est disponible: ProcessBuilder ajouté sur Java1.5. Je ne suis pas sûr de savoir de quoi il s'agit, mais il devrait y avoir une bonne raison à cela.Jetez un coup d'oeil et lisez quelle est la différence entre un Runtime.exec. Probablement ce sera une meilleure option.

Enfin, certaines commandes ne fonctionnera pas sur deux plates-formes, car ils sont construits avec la coque (soit cmd Windows ou bash/sh/etc) tels que dir ou écho et certains de ceux-ci. Je recommande donc de faire un test supplémentaire/supplémentaire sur chaque plate-forme cible et d'ajouter des gestionnaires d'exceptions pour les commandes non supportées.

:)

+0

Cela a fonctionné sur les deux systèmes d'exploitation. Merci. – Geo

1

du [api] [1]

Ce procédé vérifie que cmdarray est une commande de système d'exploitation valable . Les commandes qui sont valides sont dépendantes du système , mais au minimum , la commande doit être une liste non vide de chaînes non nulles .

Alors oui, cela dépend du système. BTW, pourriez-vous poster le code pertinent, afin que nous puissions voir ce que vous êtes (finalement) mal?

[1]: http://java.sun.com/javase/6/docs/api/java/lang/Runtime.html#exec(java.lang.String[], java.lang.String [], java.io.File)

+1

Nice, dans l'aperçu le lien n'est pas cassé! – akappa

2

D'accord, je donne: Quelle commande non-trivial vous pouvez passer à exec() et attendre à obtenir des résultats raisonnables sur Windows et Linux? Demander si exec() est indépendant de la plate-forme semble manquer tout le point de exec(), qui est d'invoquer un comportement spécifique à la plate-forme.

Pour répondre réellement à votre question, oui - la manière dont la chaîne de commande est interprétée sera différente sur différentes plateformes (et potentiellement, pour différents shells, sur Linux), et l'utilisation de la version String [] est plus susceptible de se terminer avec les paramètres se passant correctement.

+0

J'essayais d'exécuter javac pour tous les fichiers .java dans un projet, et incluais aussi les dépendances jar. – Geo

+2

Ahh, j'aurais dû deviner - exécuter des commandes JDK est une chose raisonnable à faire depuis une application Java. –

+0

@Mark. Pas vraiment ça. Les arguments des deux côtés sont différents, comme chemin/et séparateur de chemin: vs; Drives etc .. donc les commandes ne seront pas vraiment wok de manière transparente d'une plate-forme à l'autre. – OscarRyz

2

Le Tokeniser par défaut pour diviser le paramètre exec (String) en String [] les sépare simplement par le caractère espace. Il n'interprète pas les guillemets comme une commande shell entrée manuellement, vous devriez donc appeler la version String []. Mais si vous utilisez Sun JDK sur les deux plates-formes, le comportement devrait être similaire. Cependant, comme Windows fournit différentes commandes shell comme les autres systèmes d'exploitation (par exemple, copie au lieu de cp), vos commandes peuvent ne pas fonctionner sur toutes les plates-formes. Exec() appelle des commandes natives sur le système d'exploitation sous-jacent

1

Les commandes conçues pour Windows ne fonctionneront pas sous Linux et devront être réécrites.

2

La différence entre la la méthode exec() qui prend une seule chaîne, et celui qui accepte un tableau est que la version de tableau vous permet de spécifier la façon dont doivent être la commande et ses arguments rompu (c'est-à-dire correctement). Lorsque vous utilisez la ou les méthodes qui n'acceptent qu'une chaîne, la méthode la divise en un tableau sur un espace. Le traitement à partir de ce moment est traité de la même manière pour les deux méthodes.

Il s'agit du code de la classe Runtime qui montre comment il casse une chaîne unique en un tableau puis appelle String [] version pour continuer le traitement. Donc la méthode qui accepte une chaîne ne fonctionnera pas si la rupture de la commande sur whitspace ne sépare pas correctement la commande et les arguments.

1

Si vous souhaitez exécuter différentes commandes sous Windows et Linux, vous pouvez savoir sur quel système d'exploitation est en cours d'exécution en utilisant quelque chose comme ce qui suit:

 String os = System.getProperty("os.name").toLowerCase(); 
     if (os.indexOf("win") >= 0) { 
      // Windows Commands 
     } else { 
      // Linux Commands 
     } 

Une autre bonne chose serait de vous écrire êtes commandes dans un script (.bat pour Windows et .sh pour Linux) et appelez ces scripts à la place.

Questions connexes