Вещи становятся интересными, если этот сценарий оболочки является интерактивным.
Эрнесто
что такое переменная myCommand это та строка? если да, то он не будет работать, метод exec требует String [] и аргумента, см. ниже мой ответ, он отлично работает
Girdhar Singh Rathore
Ответы:
174
Вы действительно должны смотреть на Process Builder . Он действительно создан для такого рода вещей.
Это хорошая практика для вызова сценариев из JAVA? Есть проблемы с производительностью?
Каутуксани
1
Обратите внимание, что вам может потребоваться указать программу / bin / bash или sh для выполнения скрипта в зависимости от конфигурации Java (см. Stackoverflow.com/questions/25647806/… )
Бен Холланд,
@ Milhous Я знаю, что уже довольно поздно и что-то может измениться, но для текущей документации по Java-процессам этот метод не рекомендуется для сценариев оболочки: docs.oracle.com/javase/8/docs/api/java/lang/Process.html " Методы, которые создают процессы, могут не работать для специальных процессов на определенных собственных платформах, таких как собственные процессы управления окнами, процессы-демоны, процессы Win16 / DOS в Microsoft Windows или сценарии оболочки ».
@KisHanSarsecHaGajjar мы можем также захватить вывод из шеллскрипта и отобразить его в интерфейсе Java. Я хочу знать, возможно ли это сделать
Kranthi Sama
@KranthiSama Вы можете установить OutputStreamдля DefaultExecuterиспользования DefaultExecuter.setStreamHandlerметоды для вывода захвата в OutputStream. Пожалуйста, обратитесь к этой теме для получения дополнительной информации: Как я могу захватить вывод команды ...
Я бы сказал, что запускать скрипт оболочки из Java не в духе Java. Java должен быть кроссплатформенным, и запуск сценария оболочки ограничит его использование только UNIX.
С учетом сказанного, безусловно, можно запускать сценарий оболочки из Java. Вы бы использовали тот же синтаксис, который вы перечислили (я сам не пробовал, но попробуйте выполнить скрипт оболочки напрямую, и если это не сработает, запустите саму оболочку, передав скрипт в качестве параметра командной строки) ,
Да, но во многих отношениях эта мантра «дух Явы» или «пиши однажды, беги повсюду» - это миф.
BobbyShaftoe
15
Что в этом мифического?
Крис Балланс
15
что мифический о нем, что вы обычно в конечном итоге писать многочисленные switchesи ifзаявления , чтобы обойти все нюансы , которые не работают точно так же на различных платформах , несмотря на все усилия людей , которые пришли с Java основные библиотеки.
Брайан Суини
2
Довольно удивительно! Я согласен со всеми комментариями выше и ответом!
AnBisw
11
@BobbyShaftoe Я пишу Java уже 16 лет и всегда разрабатывал для Windows, все мои приложения всегда развертываются на Unix-системах со соляриком / IBM или Oracle, поэтому я понятия не имею, о чем вы говорите
Kalpesh Soni
21
Я думаю, что вы ответили на свой вопрос
Runtime.getRuntime().exec(myShellScript);
Что касается того, является ли это хорошей практикой ... что вы пытаетесь сделать с помощью сценария оболочки, который вы не можете сделать с Java?
Я столкнулся с подобной ситуацией, когда мне нужно rsync несколько файлов на разных серверах, когда в моем коде Java возникает определенное условие. Есть ли другой способ лучше?
v kumar
1
@Chris Ballance ... Я знаю, что этот комментарий почти через 10 лет :), но чтобы ответить на ваш вопрос, что если моя программа должна взаимодействовать с полдюжиной нисходящих и восходящих каналов и зависеть от принятого ими способа общения. Особенно, когда вы работаете над проектом, который взаимодействует с таким количеством странных каналов :)
Stunner
Передача функциональности в сценарий оболочки будет последней попыткой, если в Java нет другого способа выполнить эту работу. Будет непросто согласовать состояние и зависимости, если вы отправляете работу в сценарий оболочки. Иногда сценарий оболочки является единственным способом, или временные рамки делают его единственным разумным способом выполнить небольшую работу, так что это способ сделать это.
Крис Балланс
11
Да, это возможно. Это сработало для меня.
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());}}
Да, это возможно, и вы ответили на это! Что касается хороших практик, я думаю, что лучше запускать команды из файлов, а не напрямую из вашего кода. Таким образом , вы должны сделать Java выполнить список команд (или одной команды) в существующих .bat, .sh, .ksh... файлах. Вот пример выполнения списка команд в файле MyFile.sh:
Чтобы избежать жесткого кодирования абсолютного пути, вы можете использовать следующий метод, который найдет и выполнит ваш скрипт, если он находится в корневом каталоге.
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!");}}
Вот пример того, как запустить скрипт Unix bash или Windows bat / cmd из Java. Аргументы могут быть переданы в сценарий и выведены из сценария. Метод принимает произвольное количество аргументов.
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);}}
При работе в Unix / Linux путь должен быть похож на Unix (с разделителем /) в качестве разделителя, при работе в Windows - использовать \. Hier - это пример скрипта bash (test.sh), который получает произвольное количество аргументов и удваивает каждый аргумент:
Это возможно, просто выполнить его как любую другую программу. Просто убедитесь, что ваш скрипт имеет правильный #! (she-bang) в качестве первой строки скрипта и убедитесь, что для файла есть разрешения на выполнение.
Например, если это скрипт bash, поместите #! / Bin / bash в начало скрипта, также chmod + x.
Кроме того, если это хорошая практика, то нет, особенно для Java, но если это сэкономит вам много времени на перенос большого сценария, и вам не будут платить за это;) сэкономьте свое время, выполните сценарий, и поместите перенос на Java в свой долгосрочный список задач.
Это поздний ответ. Тем не менее, я подумал о том, чтобы изо всех сил пытаться заставить сценарий оболочки выполняться из приложения Spring-Boot для будущих разработчиков.
Я работал в Spring-Boot, и я не смог найти файл, который будет выполнен из моего Java-приложения, и он выбрасывал FileNotFoundFoundException. Мне нужно было сохранить файл в resourcesкаталоге и настроить файл для сканирования во pom.xmlвремя запуска приложения, как показано ниже.
После этого у меня были проблемы с выполнением файла, и он возвращался error code = 13, Permission Denied. Затем я должен был сделать файл исполняемым, выполнив эту команду -chmod u+x myShellScript.sh
Наконец, я мог выполнить файл, используя следующий фрагмент кода.
publicvoid runScript(){ProcessBuilder pb =newProcessBuilder("src/main/resources/myFile.sh");try{Process p;
p = pb.start();}catch(IOException e){
e.printStackTrace();}}
Точно так же, как в Solaris 5.10, он работает следующим образом: ./batchstart.shесть хитрость, которую я не знаю, если ваша ОС примет это \\. batchstart.shвместо этого. Эта двойная косая черта может помочь.
Проверка операционной системы может управлять сценариями оболочки / bash, если таковые поддерживаются. если есть необходимость сделать код переносимым.
Ответы:
Вы действительно должны смотреть на Process Builder . Он действительно создан для такого рода вещей.
источник
Ты можешь использовать библиотеку Apache Commons exec .
Пример :
Для дальнейшего использования, пример приведен также в Apache Doc .
источник
OutputStream
дляDefaultExecuter
использованияDefaultExecuter.setStreamHandler
методы для вывода захвата вOutputStream
. Пожалуйста, обратитесь к этой теме для получения дополнительной информации: Как я могу захватить вывод команды ...Я бы сказал, что запускать скрипт оболочки из Java не в духе Java. Java должен быть кроссплатформенным, и запуск сценария оболочки ограничит его использование только UNIX.
С учетом сказанного, безусловно, можно запускать сценарий оболочки из Java. Вы бы использовали тот же синтаксис, который вы перечислили (я сам не пробовал, но попробуйте выполнить скрипт оболочки напрямую, и если это не сработает, запустите саму оболочку, передав скрипт в качестве параметра командной строки) ,
источник
switches
иif
заявления , чтобы обойти все нюансы , которые не работают точно так же на различных платформах , несмотря на все усилия людей , которые пришли с Java основные библиотеки.Я думаю, что вы ответили на свой вопрос
Что касается того, является ли это хорошей практикой ... что вы пытаетесь сделать с помощью сценария оболочки, который вы не можете сделать с Java?
источник
Да, это возможно. Это сработало для меня.
источник
Вот мой пример. Надеюсь, это имеет смысл.
источник
Да, это возможно, и вы ответили на это! Что касается хороших практик, я думаю, что лучше запускать команды из файлов, а не напрямую из вашего кода. Таким образом , вы должны сделать Java выполнить список команд (или одной команды) в существующих
.bat
,.sh
,.ksh
... файлах. Вот пример выполнения списка команд в файлеMyFile.sh
:источник
Чтобы избежать жесткого кодирования абсолютного пути, вы можете использовать следующий метод, который найдет и выполнит ваш скрипт, если он находится в корневом каталоге.
источник
Что касается меня, все должно быть просто. Для запуска скрипта просто необходимо выполнить
источник
ZT Процесс Исполнитель является альтернативой Apache Commons Exec. Он имеет функции для запуска команд, захвата их вывода, установки таймаутов и т. Д.
Я еще не использовал это, но это выглядит достаточно хорошо документированным.
Пример из документации: Выполнение команды, перекачка stderr в логгер, возвращение вывода в виде строки UTF8.
В его документации перечислены следующие преимущества по сравнению с Commons Exec:
источник
Вот пример того, как запустить скрипт Unix bash или Windows bat / cmd из Java. Аргументы могут быть переданы в сценарий и выведены из сценария. Метод принимает произвольное количество аргументов.
При работе в Unix / Linux путь должен быть похож на Unix (с разделителем /) в качестве разделителя, при работе в Windows - использовать \. Hier - это пример скрипта bash (test.sh), который получает произвольное количество аргументов и удваивает каждый аргумент:
При звонке
в Unix / Linux вывод:
Hier - это простой сценарий Windows cmd test.cmd, который считает количество входных аргументов:
При вызове скрипта в Windows
Выход
источник
Это возможно, просто выполнить его как любую другую программу. Просто убедитесь, что ваш скрипт имеет правильный #! (she-bang) в качестве первой строки скрипта и убедитесь, что для файла есть разрешения на выполнение.
Например, если это скрипт bash, поместите #! / Bin / bash в начало скрипта, также chmod + x.
Кроме того, если это хорошая практика, то нет, особенно для Java, но если это сэкономит вам много времени на перенос большого сценария, и вам не будут платить за это;) сэкономьте свое время, выполните сценарий, и поместите перенос на Java в свой долгосрочный список задач.
источник
источник
Это поздний ответ. Тем не менее, я подумал о том, чтобы изо всех сил пытаться заставить сценарий оболочки выполняться из приложения Spring-Boot для будущих разработчиков.
Я работал в Spring-Boot, и я не смог найти файл, который будет выполнен из моего Java-приложения, и он выбрасывал
FileNotFoundFoundException
. Мне нужно было сохранить файл вresources
каталоге и настроить файл для сканирования воpom.xml
время запуска приложения, как показано ниже.error code = 13, Permission Denied
. Затем я должен был сделать файл исполняемым, выполнив эту команду -chmod u+x myShellScript.sh
Наконец, я мог выполнить файл, используя следующий фрагмент кода.
Надеюсь, что это решает чью-то проблему.
источник
Точно так же, как в Solaris 5.10, он работает следующим образом:
./batchstart.sh
есть хитрость, которую я не знаю, если ваша ОС примет это\\. batchstart.sh
вместо этого. Эта двойная косая черта может помочь.источник
Я думаю с
Проверка операционной системы может управлять сценариями оболочки / bash, если таковые поддерживаются. если есть необходимость сделать код переносимым.
источник
для использования в Linux
и для использования;
ИЛИ
источник