2010-01-27 24 views
14

Tengo dificultades para ejecutar un archivo por lotes en Java que espera parámetros. Estos parámetros pueden contener espacios, así que necesito envolverlos entre comillas. También necesitaré hacer lo mismo para Linux porque algunos de los parámetros pueden contener caracteres especiales como !.Ejecutar con los parámetros

no funcionales código de Windows:

ProcessBuilder pb = new ProcessBuilder(
     "cmd", 
     "/c", 
     "\"mybat.bat\"", 
     "\"param 1\"", 
     "\"param 2\"", 
     "\"param 3\"" 
     );  

no funcionales código de Linux:

ProcessBuilder pb = new ProcessBuilder(
     "bash", 
     "-c", 
     "'myshellscript.sh'", 
     "'param 1'", 
     "'param 2'", 
     "'param 3'" 
     ); 

entiendo que debería ser la adición de los parámetros como el ejemplo de Windows a continuación, pero esto no lo hará trabajar con los espacios:

ProcessBuilder pb = new ProcessBuilder(
     "cmd", 
     "/c", 
     "mybat.bat param 1 param 2 param 3" 
     ); 

¿Cómo se debe hacer esto?

+0

¿no es encerrarlas entre comillas por esa razón exacta? ¿Por qué no lo haces para tu último fragmento? – zneak

+0

Estoy intentando hacer que los dos primeros fragmentos funcionen. El tercer fragmento pasará 6 parámetros a mybat.bat cuando solo estoy buscando tres. –

Respuesta

17

de Windows:

ProcessBuilder pb = new ProcessBuilder(
     "cmd", "/c", "mybat.bat", 
     "param 1", "param 2", "param 3"); 

Unix:

ProcessBuilder pb = new ProcessBuilder(
     "sh", "mybat.sh", 
     "param 1", "param 2", "param 3"); 
+0

¡Intenté esto, funciona !!! –

+1

¿Por qué es esto desaire? java.io.IOException: java.io.IOException: sh: no se encuentra en java.lang.UNIXProcess. (UNIXProcess.java:148) en java.lang.ProcessImpl.start (ProcessImpl.java:65) en java.lang.ProcessBuilder.start (ProcessBuilder.java:451) en DmMdbConsumer.migrateData (DmMdbConsumer.java:328) en DmMdbConsumer.run (DmMdbConsumer.java:230) en java.lang.Thread.run (Thread.java: 595) –

+0

"sh" tenía que ser "/ bin/sh" en mi caso. ¡Gracias! –

5

No, debería no citar el argumento en * nix. Es necesario citar en * nix en un intérprete de comandos interactivo para evitar que el intérprete de comandos los malinterprete, pero al iniciar un proceso directamente, un intérprete de comandos no está involucrado. Por lo tanto, no es necesario citar.

Si incluye las comillas, el proceso lanzado las verá como parte de sus argumentos entrantes y hará cosas como (por ejemplo) intentar abrir nombres de archivo que contengan comillas.

También no desea el argumento "-c" para bash. Eso le dice que analice el siguiente argumento como una línea de comando, pero está suministrando una lista de argumentos. Elimine la opción "-c" y el exceso de comillas, y debería funcionar.

La llamada Linux adecuada sería:

ProcessBuilder pb = new ProcessBuilder(
    "bash", 
    "myshellscript.sh", 
    "param 1", 
    "param 2", 
    "param 3" 
    ); 

Además, no es que si el archivo "myshellscript.sh" es ejecutable y tiene la línea shebang apropiado (por ejemplo, "#!/Bin/bash!"), Se tampoco necesita el argumento "bash". Esto es preferible porque si el script se reemplaza alguna vez por uno escrito en un idioma diferente, no tendrá que actualizar su aplicación de llamada.

Del mismo modo, en Windows, no debería necesitar los argumentos "cmd" y "/ c". El iniciador/sistema operativo del proceso debe manejar el inicio automático del archivo por lotes (basado en la extensión).

+0

Desafortunadamente necesito el cmd y/c para Windows. Mi script de shell tiene la línea shebang, pero no puedo hacer que funcione con o sin sh. –