2010-01-27 9 views
14

Ho difficoltà a eseguire un file batch in Java che si aspetta parametri. Questi parametri possono contenere spazi, quindi ho bisogno di racchiuderli tra virgolette. Dovrò anche fare la stessa cosa per Linux perché alcuni dei parametri potrebbero contenere caratteri speciali come !.Esegui con parametri

non funzionale codice di Windows: il codice di Linux

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

non funzionale:

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

ho capito che avrei dovuto l'aggiunta di parametri come l'esempio di Windows al di sotto, ma questo non lo farà lavoro con gli spazi:

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

Come dovrebbe essere fatto?

+0

non li avete racchiudere tra virgolette per questo motivo esatto? Perché non lo stai facendo per il tuo ultimo frammento? – zneak

+0

Sto provando a far funzionare i primi due frammenti. Il terzo snippet passerà 6 parametri a mybat.bat quando sto cercando solo tre. –

risposta

17

di 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

Ho provato questo, funziona !!! –

+1

Perché questo è successo? java.io.IOException: java.io.IOException: sh: non trovato su java.lang.UNIXProcess. (UNIXProcess.java:148) in java.lang.ProcessImpl.start (ProcessImpl.java:65) in java.lang.ProcessBuilder.start (ProcessBuilder.java:451) in DmMdbConsumer.migrateData (DmMdbConsumer.java:328) in DmMdbConsumer.run (DmMdbConsumer.java:230) su java.lang.Thread.run (Thread.java: 595) –

+0

"sh" doveva essere "/ bin/sh" nel mio caso. Grazie! –

5

No, si dovrebbe non citare gli argomenti su * nix. La quotazione è necessaria su * nix in una shell interattiva per impedire che la shell li interpreti erroneamente, ma quando si avvia un processo direttamente non viene coinvolta una shell. Quindi non c'è bisogno di citare.

Se si includono le virgolette, il processo avviato le vedrà come parte dei suoi argomenti in entrata e farà cose come (ad esempio) provare ad aprire nomi di file contenenti virgolette.

Inoltre non si desidera l'argomento "-c" su bash. Questo dice di analizzare il prossimo argomento come una riga di comando, ma tu stai fornendo un elenco di argomenti. Rimuovere l'opzione "-c" e le virgolette in eccesso e dovrebbe funzionare.

La chiamata Linux corretta sarebbe:

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

Inoltre non è che se il file "myshellscript.sh" è eseguibile e ha la shebang appropriata (ad esempio "#!/Bin/bash"), è non ho nemmeno bisogno dell'argomento "bash". Questo è preferibile perché se lo script viene mai sostituito con uno scritto in una lingua diversa, non dovrai aggiornare la tua app chiamante.

Allo stesso modo, in Windows, non è necessario utilizzare gli argomenti "cmd" e "/ c". L'avvio/l'avvio del processo dovrebbe gestire automaticamente l'avvio del file batch (basato sull'estensione).

+0

Purtroppo ho bisogno del cmd e/c per Windows. Il mio script di shell ha la riga shebang, ma non riesco a farlo funzionare con o senza sh. –