Java Runtime exec() no puede escapar los caracteres correctamente
character-encoding escaping (4)
Esto ya podría haber sido respondido antes, pero eso se refería a unicode y no creo que esto sea unicode (está en ASCII entonces ...).
Cuando ejecuto esto en mi terminal no hay problema, ¿qué pasa?
vboxmanage setextradata "Test Machine" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/ssh/HostPort" 2222
Sin embargo, cuando uso lo siguiente en Java
Runtime.getRuntime().exec("vboxmanage setextradata /"Test Machine/" /"VBoxInternal/Devices/pcnet/0/LUN#0/Config/ssh/HostPort/" 2222");
Devuelve un error: vm no registrado ''"TestMachine"''
Lo mismo ocurre con los parámetros con espacios en ellos como Test / Machine, y luego no escapa al espacio.
Ahora creo que esto tiene algo que ver con la codificación de caracteres, pero no veo ninguna opción para configurar eso o_O
En lugar de intentar citar la línea de comando, es mejor que ProcessBuilder.command(arg0, arg1, ...)
Ver ProcessBuilder para más detalles.
Está llamando al programa y sus argumentos de una sola vez, lo que efectivamente coloca toda la cadena en el entorno de procesamiento (esperando lo mejor).
En los sistemas Windows, el sistema operativo se encarga de manejar el ejecutable y los argumentos de manera diferente, y ponerlos todos en la misma cadena solo requiere que elijas la cadena perfecta que el entorno (de los cuales hay dos que conozco) puede -parse en una lista de argumentos. La mejor solución es usar
Runtime.exec(new String[] {"vboxmanage", "setextradata", "Test Machine", "VBoxInternal/Devices/pcnet/0/LUN#0/Config/ssh/HostPort", "2222"});
que corresponde a Runtime''s
public Process exec(String[] cmdarray)
throws IOException
En el mejor de los casos, con el método de una cadena eventualmente descubrirá cómo insinuar y escapar de los argumentos para que no sean tratados como parte del nombre del ejecutable, pero luego se encontrará con un problema nuevo, que se aprobará todo como un parámetro para el ejecutable. Una vez que arregle eso dependiendo del entorno, o encontrará que sus presupuestos no se eliminan de los parámetros (lo que lleva a parámetros como "2222") o que el análisis de argumentos semi-rotos de Windows se analizará primero en espacios en blanco ( lo que lleva a parámetros como ("Prueba). No tiene sentido, es por eso que hay más de un método exec
disponible.
Usar Runtime.exec(String)
es el método incorrecto para este caso (y generalmente el método incorrecto para pasar argumentos al nuevo proceso).
Use una de las sobrecargas ejecutivas que toma una matriz de argumentos para pasar al nuevo proceso. (O bien, vea la respuesta de Paul con ProcessBuilder: ninguno de estos enfoques tiene problemas de escape).
Ejemplo:
exec(new String[] { "vbomanager",
"setextradata", "Test Machine",
"VBoxInternal/Devices/pcnet/0/LUN#0/Config/ssh/HostPort", "2222"});
Feliz codificación.
En Windows, Runtime.exec (String []) tampoco es seguro. Si el argumento matriz contiene la cadena vacía, el argumento vacío se omite básicamente, lo que puede conducir a una línea de comando no válida. Además, las comillas dentro de cualquiera de los argumentos no tienen prefijos con barras diagonales inversas. Además, ProcessBuilder puede agregar comillas a argumentos sin duplicar el número de barras diagonales anteriores, lo que da resultados graciosos si uno pasa una ruta a una carpeta como c: / archivos de programa / incluyendo la barra diagonal inversa.
La documentación de Microsoft de su tokenizador de línea de comandos está disponible aquí: http://msdn.microsoft.com/en-us/library/a1y7w461.aspx
Los problemas que describí están documentados aquí: http://bugs.sun.com/view_bug.do?bug_id=6468220 y http://bugs.sun.com/view_bug.do?bug_id=6518827