2010-01-27 15 views
14

Mam trudności z wykonywaniem pliku wsadowego w języku Java, który oczekuje parametrów. Te parametry mogą zawierać spacje, więc muszę je zawijać w cudzysłów. Będę również musiał zrobić to samo dla Linuksa, ponieważ niektóre parametry mogą zawierać znaki specjalne, takie jak !.Wykonanie z parametrami

niefunkcjonalne kod Windows:

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

niefunkcjonalne kod Linux:

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

Rozumiem, że należy dodać parametry jak na przykładzie poniżej systemu Windows, ale nie będzie to pracować ze spacjami:

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

Jak należy to zrobić?

+0

Nie ująć je w cudzysłów dla tego dokładnie powodu? Dlaczego nie robisz tego dla swojego ostatniego fragmentu? – zneak

+0

Próbuję wykonać pierwsze dwa fragmenty kodu. Trzeci fragment przekazuje 6 parametrów do pliku mybat.bat, gdy szukam tylko trzech. –

Odpowiedz

17

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

Próbowałem tego, działa !!! –

+1

Dlaczego to się dzieje? java.io.IOException: java.io.IOException: sh: nie znaleziono na java.lang.UNIXProcess. (UNIXProcess.java:148) w java.lang.ProcessImpl.start (ProcessImpl.java:65) w java.lang.ProcessBuilder.start (ProcessBuilder.java:451) at DmMdbConsumer.migrateData (DmMdbConsumer.java:328) at DmMdbConsumer.run (DmMdbConsumer.java:230) w java.lang.Thread.run (Thread.java: 595) –

+0

"sh" musiało być "/ bin/sh" w moim przypadku. Dzięki! –

5

Nie, powinieneś nie zacytować args na * nix. Cytowanie jest konieczne na * nix w powłoce interaktywnej, aby zapobiec błędnej interpretacji przez powłokę, ale przy uruchamianiu procesu bezpośrednio nie jest zaangażowana powłoka. Dlatego nie trzeba zacytować.

Jeśli uwzględnisz cytaty, uruchomiony proces zobaczy je jako część przychodzących argumentów i wykona takie czynności jak (na przykład) próba otwarcia nazw plików zawierających cytaty.

Nie chcesz też bashować argumentu "-c". To każe parsować następny argument jako linię poleceń, ale podajesz listę argumentów. Usuń opcję "-c" i nadmiarowe cytaty i powinno działać.

Prawidłowe wezwanie Linux będzie:

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

też nie, że jeśli plik "myshellscript.sh" jest wykonywalny i ma odpowiednią linię shebang (np "#!/Bin/bash!"), Ty nie trzeba też argumentu "bash". Jest to preferowane, ponieważ jeśli skrypt zostanie zastąpiony kiedykolwiek pisanym w innym języku, nie będziesz musiał aktualizować aplikacji do połączeń.

Podobnie, w systemie Windows, nie powinieneś potrzebować argumentów "cmd" i "/ c". Program uruchamiający proces/system operacyjny powinien obsługiwać automatyczne uruchamianie pliku wsadowego (na podstawie rozszerzenia).

+0

Niestety potrzebuję cmd i/c dla Windows. Mój skrypt powłoki ma linię shebang, ale nie mogę jej uruchomić z sh lub bez. –