2009-04-13 30 views
28

En mis argumentos de la línea de comandos de Java, se ignoran los caracteres después del espacio. Por ejemplo,espacio en los argumentos de línea de comandos de Java

java test.AskGetCampaignByName "Dummy books" 

Obtengo el primer argumento (args [0]) como "Dummy" solamente. Las comillas simples tampoco ayudan. ¿Alguien sabe alguna solución/solución para esto? ¿Podría ser por mi configuración de terminal? Mi $ TERM es xterm, y $ LANG es "en_IN".

Respuesta

53

Los argumentos son manejados por el intérprete de comandos (supongo que está utilizando bash en Linux?), Por lo que las configuraciones de terminal no deberían afectar esto. Como ya has citado el argumento, debería funcionar. La única explicación posible que puedo pensar es si su comando java es un script de contenedor y arruina el escape de los argumentos al pasar al programa real. Esto es fácil de hacer, o quizás un poco difícil de hacer correctamente.

Un script de contenedor correcto debe pasar todos sus argumentos como ${1+"[email protected]"}, cualquier otra versión es muy probablemente un error con respecto a poder manejar los espacios integrados correctamente. No es raro hacerlo correctamente, sin embargo, cualquier ocurrencia de $2 o similar es problemática y debe escribirse como "$2" (o posiblemente ${2+"$2"}) para manejar correctamente los espacios integrados, y esto se debe a muchos.

La razón de la sintaxis no es tan intuitivo ${1+"[email protected]"} que el original $* se unieron todos los argumentos que "$1 $2 $3 ..." que no funcionaba para espacios incrustados. Luego se introdujo "[email protected]" que (correctamente) se expandió a "$1" "$2" "$3" ... para todos los parámetros y, si no se proporcionan parámetros, debería expandirse a nada. Desafortunadamente, un vendedor de Unix cometió un error e hizo que "[email protected]" se expandiera a "" incluso en el caso de que no hubiera argumentos, y para solucionar esto se inventó el hack inteligente (pero no tan legible) ${1+"[email protected]"}, haciendo que "[email protected]" solo se expanda si se establece el parámetro $1 evitando la expansión en caso de no tener argumentos).

Si mi suposición es incorrecta envoltorio se podría intentar depurar con strace

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

y averiguar qué argumentos se pasan a execve. Ejemplo de correr "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

Muchas gracias hlovdal! Ese fue exactamente el caso. Generamos un ejecutable a través de ant build que establece los classpaths etc. Y usamos "java @" en el script. Sustituir tu $ {1 + "@"} resolvió el problema. Lo siento por engañar al usar Java directamente en mi ejemplo. Supuse que significa lo mismo – ashweta

0

En caso de que su programa necesite más que argumentos posicionales (= cuando el uso de la línea de comandos es importante), debe considerar opciones e interruptores. Apache Commons tiene una gran library para esto.

0

Parece que está utilizando una distribución de sistema operativo donde el comando java disponible para el usuario es un contenedor que encuentra la JVM correcta "en algún lugar" y la invoca en consecuencia.

Si es así, lo más probable es que no escape a los argumentos correctamente al invocar el ejecutable real de Java.

¿Qué distribución usas?

+0

En mi máquina de Windows ' "hola mundo" "hola mundo" "hola mundo"' pasa como argumentos de línea de comandos serán recogidos como args [0 (/ 1) (/ 2)] == "hello world" y en Linux esto simplemente no funciona (no recuerdo lo que * does * do, ya que no estaba demasiado preocupado). Pero me gustaría ver alguna solución a esto. Gracias por la pregunta. @ Thorbjørn Ravn Andersen, por favor, elabore. ¿Cómo puedo cambiar la forma en que se invoca JVM? –

-3

Esta pregunta es un poco viejo, pero ¿por qué no acaba de volver a montar los argumentos en el programa 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

Porque 'java test.AskGetCampaignByName" Dummy books "' con espacios múltiples entre 'Dummy' y' books' fallaría (que Stack Overflow genera como un espacio único, por lo que no puede verlo aquí. ..) – leemes

+0

Porque 'java' debería obtener los argumentos de línea de comandos correctamente desde el shell para comenzar. – Olathe

1

sólo hay que escapar de los espacios como este:

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

que trabajó para mí.

Mi entorno:

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

No escapó a nada, solo dividió un argumento en dos argumentos que no es lo que el OP estaba pidiendo. Los espacios no necesitan escaparse, simplemente necesitan ser citados. –

Cuestiones relacionadas