Rzeczy stają się interesujące, jeśli ten skrypt powłoki jest interaktywny.
ernesto
co to jest zmienna myCommand to String? jeśli tak, to nie zadziała, metoda exec wymaga String [] i argumentu, patrz poniżej moja answar, działa idealnie
Girdhar Singh Rathore
Odpowiedzi:
174
Powinieneś naprawdę spojrzeć na Process Builder . Jest naprawdę zbudowany do tego typu rzeczy.
Czy jest dobrą praktyką wywoływanie skryptów z JAVA? Jakieś problemy z wydajnością?
kautuksahni
1
Zwróć uwagę, że może być konieczne określenie programu / bin / bash lub sh w celu wykonania skryptu w zależności od konfiguracji Javy (patrz stackoverflow.com/questions/25647806/ ... )
Ben Holland
@Milhous Wiem, że to dość późno i mogło się to zmienić, ale zgodnie z aktualną dokumentacją procesu Java nie jest to zalecana metoda dla skryptów powłoki: docs.oracle.com/javase/8/docs/api/java/lang/Process.html " Metody tworzące procesy mogą nie działać dobrze w przypadku specjalnych procesów na niektórych natywnych platformach, takich jak natywne procesy okienkowe, procesy demonów, procesy Win16 / DOS w systemie Microsoft Windows lub skrypty powłoki ”.
@KisHanSarsecHaGajjar możemy również przechwycić dane wyjściowe z shellscript i wyświetlić je w java ui. Chcę wiedzieć, czy można to zrobić
Kranthi Sama
@KranthiSama można ustawić OutputStreamna DefaultExecuterużyciu DefaultExecuter.setStreamHandlermetody przechwytywania w wyjściu OutputStream. Zapoznaj się z tym wątkiem, aby uzyskać więcej informacji: Jak mogę przechwycić dane wyjściowe polecenia ...
Powiedziałbym, że nie jest to duch Javy uruchamianie skryptu powłoki z Javy. Java ma być wieloplatformowa, a uruchomienie skryptu powłoki ograniczyłoby jej użycie tylko do systemu UNIX.
Mając to na uwadze, zdecydowanie możliwe jest uruchomienie skryptu powłoki z poziomu Javy. Użyłbyś dokładnie tej samej składni, którą podałeś (sam tego nie próbowałem, ale spróbuj wykonać skrypt powłoki bezpośrednio, a jeśli to nie zadziała, uruchom samą powłokę, przekazując skrypt jako parametr wiersza poleceń) .
Tak, ale pod wieloma względami ta mantra „duch Javy” lub „pisz raz, biegnij wszędzie” jest i tak mitem.
BobbyShaftoe
15
Co w tym jest mityczne?
Chris Ballance,
15
co o nim jest mityczny, które zwykle kończą się pisząc liczne switchesi ifsprawozdań, aby ominąć wszystkie niuanse, które nie działają dokładnie tak samo na różnych platformach mimo najlepszych starań ludzi, którzy wpadli na bibliotekach rdzenia java.
Brian Sweeney
2
Zaskakujące! Zgadzam się ze wszystkimi powyższymi komentarzami i odpowiedzią!
AnBisw
11
@BobbyShaftoe Piszę Javę od 16 lat i zawsze tworzyłem pod Windows, wszystkie moje aplikacje zawsze były wdrażane na skrzynkach unix o smaku solaris / ibm lub Oracle, więc nie mam pojęcia, o czym mówisz
Kalpesh Soni
21
Myślę, że odpowiedziałeś na swoje pytanie za pomocą
Runtime.getRuntime().exec(myShellScript);
Co do tego, czy jest to dobra praktyka ... co próbujesz zrobić ze skryptem powłoki, którego nie możesz zrobić w Javie?
Miałem do czynienia z podobną sytuacją, w której muszę zsynchronizować kilka plików na różnych serwerach, gdy wystąpi określony stan w moim kodzie java. Czy jest inny lepszy sposób?
v kumar
1
@Chris Ballance ... Wiem, że ten komentarz jest już prawie po 10 latach :) ale odpowiadając na twoje pytanie, co jeśli mój program będzie musiał współdziałać z pół tuzinem kanałów downstream i upstream i uzależniony od przyjętego przez nie sposobu komunikacji. Zwłaszcza gdy pracujesz nad projektem, który współdziała z tak wieloma dziwnymi kanałami :)
Stunner
Przekazanie funkcjonalności do skryptu powłoki byłoby wysiłkiem na ostatnią chwilę, gdyby nie było innego sposobu wykonania pracy w Javie. Koordynacja stanu i zależności będzie z konieczności skomplikowana, jeśli wypychasz pracę do skryptu powłoki. Czasami skrypt powłoki jest jedynym sposobem lub ramy czasowe sprawiają, że jest to jedyny rozsądny sposób na wykonanie jakiejś pracy, więc jest to sposób na zrobienie tego.
Chris Ballance
11
Tak, jest to możliwe. To mi się udało.
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import org.omg.CORBA.portable.InputStream;publicstaticvoid readBashScript(){try{Process proc =Runtime.getRuntime().exec("/home/destino/workspace/JavaProject/listing.sh /");//Whatever you want to executeBufferedReader read =newBufferedReader(newInputStreamReader(
proc.getInputStream()));try{
proc.waitFor();}catch(InterruptedException e){System.out.println(e.getMessage());}while(read.ready()){System.out.println(read.readLine());}}catch(IOException e){System.out.println(e.getMessage());}}
Tak, jest to możliwe i odpowiedziałeś na to! Co do dobrych praktyk, myślę, że lepiej jest uruchamiać polecenia z plików, a nie bezpośrednio z kodu. Więc trzeba zrobić Java wykonać listę poleceń (lub jednego polecenia) w istniejącej .bat, .sh, .ksh... plików. Oto przykład wykonania listy poleceń w pliku MyFile.sh:
Aby uniknąć konieczności kodowania bezwzględnej ścieżki na stałe, możesz użyć następującej metody, która znajdzie i uruchomi skrypt, jeśli znajduje się on w katalogu głównym.
publicstaticvoid runScript()throwsIOException,InterruptedException{ProcessBuilder processBuilder =newProcessBuilder("./nameOfScript.sh");//Sets the source and destination for subprocess standard I/O to be the same as those of the current Java process.
processBuilder.inheritIO();Process process = processBuilder.start();int exitValue = process.waitFor();if(exitValue !=0){// check for errorsnewBufferedInputStream(process.getErrorStream());thrownewRuntimeException("execution of script failed!");}}
Wykonawca ZT Sposób jest alternatywą dla Apache Commons Exec. Posiada funkcję uruchamiania poleceń, przechwytywania ich danych wyjściowych, ustawiania limitów czasu itp.
Nie korzystałem jeszcze z niego, ale wygląda na dość dobrze udokumentowany.
Przykład z dokumentacji: Wykonanie polecenia, przepompowanie stderr do loggera, zwrócenie danych wyjściowych jako łańcuch znaków UTF8.
Oto przykład, jak uruchomić skrypt bash Unix lub Windows bat / cmd z poziomu Java. Argumenty mogą być przekazywane do skryptu i dane wyjściowe otrzymane ze skryptu. Metoda przyjmuje dowolną liczbę argumentów.
publicstaticvoid runScript(String path,String... args){try{String[] cmd =newString[args.length +1];
cmd[0]= path;int count =0;for(String s : args){
cmd[++count]= args[count -1];}Process process =Runtime.getRuntime().exec(cmd);BufferedReader bufferedReader =newBufferedReader(newInputStreamReader(process.getInputStream()));try{
process.waitFor();}catch(Exception ex){System.out.println(ex.getMessage());}while(bufferedReader.ready()){System.out.println("Received from script: "+ bufferedReader.readLine());}}catch(Exception ex){System.out.println(ex.getMessage());System.exit(1);}}
W przypadku pracy w systemie Unix / Linux ścieżka musi być podobna do systemu Unix (z „/” jako separatorem), w przypadku uruchamiania w systemie Windows - należy użyć „\”. Hier to przykład skryptu bash (test.sh), który otrzymuje dowolną liczbę argumentów i podwaja każdy argument:
Jest to możliwe, po prostu wykonaj to jak każdy inny program. Tylko upewnij się, że Twój skrypt ma poprawny #! (she-bang) jako pierwszą linię skryptu i upewnij się, że plik ma uprawnienia do wykonywania.
Na przykład, jeśli jest to skrypt bash, umieść #! / Bin / bash na górze skryptu, również chmod + x.
Również jeśli chodzi o dobrą praktykę, nie, zwłaszcza w przypadku Javy, ale jeśli oszczędza ci to dużo czasu przy przenoszeniu dużego skryptu i nie dostajesz za to dodatkowej zapłaty;) oszczędzaj czas, wykonaj script i umieść portowanie na Javę na długoterminowej liście rzeczy do zrobienia.
To jest późna odpowiedź. Pomyślałem jednak o podjęciu trudu, jaki musiałem znieść, aby skrypt powłoki był uruchamiany z aplikacji Spring-Boot dla przyszłych programistów.
Pracowałem w Spring-Boot i nie mogłem znaleźć pliku do wykonania w mojej aplikacji Java i wyrzucał FileNotFoundFoundException. Musiałem zachować plik w resourceskatalogu i ustawić plik do skanowania pom.xmlpodczas uruchamiania aplikacji, jak poniżej.
Potem miałem problemy z uruchomieniem pliku i wracał error code = 13, Permission Denied. Następnie musiałem uczynić plik wykonywalnym, uruchamiając to polecenie -chmod u+x myShellScript.sh
Wreszcie mogłem uruchomić plik za pomocą następującego fragmentu kodu.
publicvoid runScript(){ProcessBuilder pb =newProcessBuilder("src/main/resources/myFile.sh");try{Process p;
p = pb.start();}catch(IOException e){
e.printStackTrace();}}
Tak samo, jak w Solarisie 5.10, działa w ten sposób ./batchstart.sh, jest też sztuczka, której nie wiem, jeśli Twój system operacyjny ją akceptuje \\. batchstart.sh. To podwójne ukośnik może pomóc.
Odpowiedzi:
Powinieneś naprawdę spojrzeć na Process Builder . Jest naprawdę zbudowany do tego typu rzeczy.
źródło
Możesz użyć biblioteki exec Apache Commons .
Przykład:
W celu uzyskania dalszych informacji, podano również przykład w Apache Doc .
źródło
OutputStream
naDefaultExecuter
użyciuDefaultExecuter.setStreamHandler
metody przechwytywania w wyjściuOutputStream
. Zapoznaj się z tym wątkiem, aby uzyskać więcej informacji: Jak mogę przechwycić dane wyjściowe polecenia ...Powiedziałbym, że nie jest to duch Javy uruchamianie skryptu powłoki z Javy. Java ma być wieloplatformowa, a uruchomienie skryptu powłoki ograniczyłoby jej użycie tylko do systemu UNIX.
Mając to na uwadze, zdecydowanie możliwe jest uruchomienie skryptu powłoki z poziomu Javy. Użyłbyś dokładnie tej samej składni, którą podałeś (sam tego nie próbowałem, ale spróbuj wykonać skrypt powłoki bezpośrednio, a jeśli to nie zadziała, uruchom samą powłokę, przekazując skrypt jako parametr wiersza poleceń) .
źródło
switches
iif
sprawozdań, aby ominąć wszystkie niuanse, które nie działają dokładnie tak samo na różnych platformach mimo najlepszych starań ludzi, którzy wpadli na bibliotekach rdzenia java.Myślę, że odpowiedziałeś na swoje pytanie za pomocą
Co do tego, czy jest to dobra praktyka ... co próbujesz zrobić ze skryptem powłoki, którego nie możesz zrobić w Javie?
źródło
Tak, jest to możliwe. To mi się udało.
źródło
Oto mój przykład. Mam nadzieję, że to ma sens.
źródło
Tak, jest to możliwe i odpowiedziałeś na to! Co do dobrych praktyk, myślę, że lepiej jest uruchamiać polecenia z plików, a nie bezpośrednio z kodu. Więc trzeba zrobić Java wykonać listę poleceń (lub jednego polecenia) w istniejącej
.bat
,.sh
,.ksh
... plików. Oto przykład wykonania listy poleceń w plikuMyFile.sh
:źródło
Aby uniknąć konieczności kodowania bezwzględnej ścieżki na stałe, możesz użyć następującej metody, która znajdzie i uruchomi skrypt, jeśli znajduje się on w katalogu głównym.
źródło
Jeśli chodzi o mnie, wszystko musi być proste. Do uruchomienia skryptu wystarczy wykonać
źródło
Wykonawca ZT Sposób jest alternatywą dla Apache Commons Exec. Posiada funkcję uruchamiania poleceń, przechwytywania ich danych wyjściowych, ustawiania limitów czasu itp.
Nie korzystałem jeszcze z niego, ale wygląda na dość dobrze udokumentowany.
Przykład z dokumentacji: Wykonanie polecenia, przepompowanie stderr do loggera, zwrócenie danych wyjściowych jako łańcuch znaków UTF8.
Jego dokumentacja wymienia następujące zalety w porównaniu z Commons Exec:
źródło
Oto przykład, jak uruchomić skrypt bash Unix lub Windows bat / cmd z poziomu Java. Argumenty mogą być przekazywane do skryptu i dane wyjściowe otrzymane ze skryptu. Metoda przyjmuje dowolną liczbę argumentów.
W przypadku pracy w systemie Unix / Linux ścieżka musi być podobna do systemu Unix (z „/” jako separatorem), w przypadku uruchamiania w systemie Windows - należy użyć „\”. Hier to przykład skryptu bash (test.sh), który otrzymuje dowolną liczbę argumentów i podwaja każdy argument:
Dzwoniąc
w systemie Unix / Linux dane wyjściowe to:
Hier jest prostym skryptem cmd test.cmd, który zlicza argumenty wejściowe:
Podczas wywoływania skryptu w systemie Windows
Wynik jest
źródło
Jest to możliwe, po prostu wykonaj to jak każdy inny program. Tylko upewnij się, że Twój skrypt ma poprawny #! (she-bang) jako pierwszą linię skryptu i upewnij się, że plik ma uprawnienia do wykonywania.
Na przykład, jeśli jest to skrypt bash, umieść #! / Bin / bash na górze skryptu, również chmod + x.
Również jeśli chodzi o dobrą praktykę, nie, zwłaszcza w przypadku Javy, ale jeśli oszczędza ci to dużo czasu przy przenoszeniu dużego skryptu i nie dostajesz za to dodatkowej zapłaty;) oszczędzaj czas, wykonaj script i umieść portowanie na Javę na długoterminowej liście rzeczy do zrobienia.
źródło
źródło
To jest późna odpowiedź. Pomyślałem jednak o podjęciu trudu, jaki musiałem znieść, aby skrypt powłoki był uruchamiany z aplikacji Spring-Boot dla przyszłych programistów.
Pracowałem w Spring-Boot i nie mogłem znaleźć pliku do wykonania w mojej aplikacji Java i wyrzucał
FileNotFoundFoundException
. Musiałem zachować plik wresources
katalogu i ustawić plik do skanowaniapom.xml
podczas uruchamiania aplikacji, jak poniżej.error code = 13, Permission Denied
. Następnie musiałem uczynić plik wykonywalnym, uruchamiając to polecenie -chmod u+x myShellScript.sh
Wreszcie mogłem uruchomić plik za pomocą następującego fragmentu kodu.
Mam nadzieję, że to rozwiązuje czyjś problem.
źródło
Tak samo, jak w Solarisie 5.10, działa w ten sposób
./batchstart.sh
, jest też sztuczka, której nie wiem, jeśli Twój system operacyjny ją akceptuje\\. batchstart.sh
. To podwójne ukośnik może pomóc.źródło
Myślę z
Sprawdzenie systemu operacyjnego może zarządzać skryptami powłoki / bash, jeśli takie są obsługiwane. jeśli istnieje potrzeba, aby kod był przenośny.
źródło
do użytku w systemie Linux
i do użytku;
LUB
źródło