2009-04-13 8 views
28

Dans mes arguments de ligne de commande Java, les caractères après l'espace sont ignorés. Par exemple,espace dans les arguments de ligne de commande Java

java test.AskGetCampaignByName "Dummy books" 

Je reçois le premier argument (args [0]) uniquement comme "Dummy". Les guillemets simples n'aident pas non plus. Quelqu'un sait-il une solution de contournement/correctif pour cela? Serait-ce à cause de mes paramètres de terminal? Mon $ TERM est xterm, et $ LANG est "en_IN".

Répondre

53

Les arguments sont traités par le shell (je suppose que vous utilisez bash sous linux?), Donc les paramètres du terminal ne devraient pas affecter cela. Puisque vous avez déjà cité l'argument, cela devrait fonctionner. La seule explication possible que je peux penser est si votre commande java est un script de wrapper et salit l'échappement des arguments lors de la transmission au vrai programme. C'est facile à faire, ou peut-être un peu difficile à faire correctement. Un script wrapper correct doit passer tous ses arguments sur ${1+"[email protected]"}, toute autre version est probablement un bogue en ce qui concerne la gestion correcte des espaces incorporés. Ce n'est pas rare à faire correctement, cependant toutes les occurrences de $2 ou similaire sont gênantes et doivent être écrites comme "$2" (ou éventuellement ${2+"$2"}) afin de gérer correctement les espaces incorporés, et ceci est péché contre beaucoup.

La raison de la syntaxe pas si intuitive ${1+"[email protected]"} est que l'original $* a joint tous les arguments comme "$1 $2 $3 ..." qui ne fonctionnait pas pour les espaces incorporés. Puis "[email protected]" a été introduit que (correctement) étendu à "$1" "$2" "$3" ... pour tous les paramètres et si aucun paramètre n'est donné, il devrait s'étendre à rien. Malheureusement, certains fournisseurs d'Unix se sont trompés et ont fait "[email protected]" étendre à "" même en l'absence d'arguments, et pour contourner ce problème, le piratage intelligent (mais pas si lisible) de l'écriture ${1+"[email protected]"} a été inventé, rendant "[email protected]" uniquement si le paramètre $1 est activé (ie éviter l'expansion en l'absence d'arguments).

Si mon hypothèse d'emballage est erroné, vous pouvez essayer de déboguer avec strace

strace -o outfile -f -ff -F java test.AskGetCampaignByName "Dummy books" 

et savoir quels arguments sont passés à execve. Exemple de fonctionnement « strace /bin/echo '1 2' 3 »

execve("/bin/echo", ["/bin/echo", "1 2", "3"], [/* 93 vars */]) = 0 
brk(0)         = 0x2400000 
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f420075b000 
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f420075a000 
access("/etc/ld.so.preload", R_OK)  = -1 ENOENT (No such file or directory) 
open("/usr/lib64/alliance/lib/tls/x86_64/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) 
stat("/usr/lib64/alliance/lib/tls/x86_64", 0x7fff08757cd0) = -1 ENOENT (No such file or directory) 
open("/usr/lib64/alliance/lib/tls/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) 
... 
+1

Merci beaucoup hlovdal! C'était exactement le cas. Nous générons un exécutable à l'aide de la construction ant qui définit les chemins de classes, etc. Et nous utilisions "java @" dans le script. La substitution de votre $ {1 + "@"} a résolu le problème. Désolé de tromper en utilisant java directement dans mon exemple. Je supposais que cela signifiait la même chose – ashweta

0

Si votre programme nécessite plus que des arguments positionnels (= lorsque l'utilisation de la ligne de commande est importante), vous devez prendre en compte les options et les commutateurs. Apache Commons a un bon library pour cela.

0

On dirait que vous utilisez une distribution de système d'exploitation où la commande java accessible à l'utilisateur est un wrapper qui trouve la bonne machine virtuelle "quelque part" et l'invoque en conséquence.

Si tel est le cas, il n'atteint probablement pas correctement les arguments lors de l'appel de l'exécutable java.

Quelle distribution utilisez-vous?

+0

Sur ma machine Windows ' "Bonjour tout le monde" "Bonjour tout le monde" "Bonjour tout le monde"' passé comme arguments de ligne de commande seront ramassées comme args [0 (/ 1) (/ 2)] == "hello world" et sur Linux ça ne marche tout simplement pas (je ne me souviens pas de ce que * fait *, car je n'étais pas trop concerné). Mais je serais heureux de voir toute solution à cela. Merci pour la question. @ Thorbjørn Ravn Andersen, s'il vous plaît élaborer. Comment puis-je changer la manière dont JVM est appelée? –

-3

Cette question est un peu vieux, mais pourquoi ne pas vous remonter juste les args dans votre programme java?

StringBuilder allArgs = new StringBuilder(); 
for (int i=0; i < args.length; i++) 
{ 
    //System.out.println("arg"+i+": "+args[i]); 
    allArgs.append(args[i]+" "); 
} 
//Parse out the args the way you wish using allArgs 
+0

Parce que 'java test.AskGetCampaignByName" Dummy books "' avec plusieurs espaces entre 'Dummy' et' books' échouerait (Stack Overflow sort en tant qu'espace unique, donc vous ne pouvez pas le voir ici. ..) – leemes

+0

Parce que 'java' devrait obtenir les arguments de ligne de commande correctement à partir du shell pour commencer. – Olathe

1

Il vous suffit d'échapper aux espaces comme celui-ci:

normal String: "Hello World!" 
escaped String: "Hello" "World!" 

Cela a fonctionné pour moi.

Mon environnement:

23:39:19 [email protected]:/Users/Zarathustra~$bash -version 
GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin11) 
Copyright (C) 2007 Free Software Foundation, Inc. 
+2

Vous n'avez rien échappé, vous avez juste cassé un seul argument en deux arguments ce qui n'est pas du tout ce que l'OP demandait. Les espaces n'ont pas besoin d'être échappés, ils ont simplement besoin d'être cités. –

Questions connexes