Java выполнить команду linux

Выполнение команд оболочки с помощью Java

В этом уроке мы рассмотрим, как выполнять команды оболочки, файлы bat и sh на Java. Мы рассмотрим примеры для всех подходов exec() и ProcessBuilder.

Автор: David Landup
Дата записи

Вступление

В этой статье мы рассмотрим, как мы можем использовать классы Runtime и ProcessBuilder для выполнения команд и сценариев оболочки с помощью Java.

Мы используем компьютеры для автоматизации многих вещей в нашей повседневной работе. Системные администраторы постоянно выполняют множество команд, некоторые из которых очень повторяющиеся и требуют минимальных изменений в промежутках между запусками.

Этот процесс также созрел для автоматизации. Нет необходимости запускать все вручную. Используя Java, мы можем запускать одну или несколько команд оболочки, выполнять сценарии оболочки, запускать терминал/командную строку, устанавливать рабочие каталоги и управлять переменными среды с помощью основных классов.

Время выполнения.exec()

Класс Runtime в Java-это класс высокого уровня, присутствующий в каждом отдельном приложении Java. Через него само приложение взаимодействует с окружающей средой, в которой оно находится.

Извлекая среду выполнения, связанную с нашим приложением, с помощью метода getRuntime () , мы можем использовать метод exec() для прямого выполнения команд или запуска файлов .bat /|. sh .

Метод exec() предлагает несколько перегруженных вариантов:

  • публичный процесс exec(строковая команда) – Выполняет команду, содержащуюся в command , в отдельном процессе.
  • публичный процесс exec(строковая команда, Строка[] envp) – Выполняет команду | с массивом переменных среды. Они представлены в виде массива строк, следующих за форматом имя=значение . публичный процесс exec(Строковая команда, Строка[] envp, директория файла)
  • — Выполняет команду с указанными переменными среды из каталога | каталога. публичный процесс exec(Строка cmdArray[]) – Выполняет команду в виде массива строк.
  • публичный процесс exec(Строка cmdArray[], Строка[] envp) – Выполняет команду с указанными переменными среды.
  • публичный процесс exec(Строка cmdarray[], Строка[] envp, файл dir) – Выполняет команду с указанными переменными среды из каталога
  • dir .

Стоит отметить, что эти процессы запускаются извне из интерпретатора и будут зависеть от системы.

Что также стоит отметить, так это разницу между Строковой командой и Строковой командой cmdArray[] . Они достигают одного и того же. Команда | в любом случае разбивается на массив, поэтому использование любого из этих двух должно привести к одинаковым результатам.

Вам решать, хотите ли вы использовать exec(«директория/папка») или exec(новая строка[] <"директория", "/папка">.

Давайте приведем несколько примеров, чтобы увидеть, чем эти перегруженные методы отличаются друг от друга.

Выполнение команды из строки

Давайте начнем с самого простого подхода из этих трех:

Запуск этого кода приведет к выполнению команды, которую мы предоставили в строковом формате. Однако мы ничего не видим, когда запускаем это.

Чтобы проверить, правильно ли это выполнено, мы захотим получить доступ к объекту process . Давайте воспользуемся BufferedReader , чтобы взглянуть на то, что происходит:

Теперь, когда мы запускаем этот метод после метода exec () , он должен дать что-то вроде:

Имейте в виду, что нам придется извлекать информацию о процессе из экземпляров Process , когда мы будем рассматривать другие примеры.

Укажите рабочий каталог

Если вы хотите запустить команду, скажем, из определенной папки, мы бы сделали что-то вроде:

Здесь мы предоставили методу exec() команду , null для новых переменных среды и новый файл () , который установлен в качестве вашего рабочего каталога.

Стоит отметить добавление cmd/c перед такой командой, как dir .

Поскольку я работаю в Windows, это открывает cmd и /c выполняет последующую команду. В данном случае это реж. .

Причина, по которой это не было обязательным для примера ping , но является обязательным для этого примера, хорошо ответил пользователь SO.

Читайте также:  Kali linux как сменить язык системы

Запуск предыдущего фрагмента кода приведет к:

Давайте посмотрим, как мы могли бы предоставить предыдущую команду в нескольких отдельных частях, а не в одной строке:

Запуск этого фрагмента кода также приведет к:

В конечном счете, независимо от подхода – с использованием одной строки или массива строк, вводимая вами команда всегда будет разбита на массив перед обработкой базовой логикой.

Какой из них вы хотели бы использовать, сводится только к тому, какой из них вы считаете более читабельным.

Использование Переменных Среды

Давайте посмотрим, как мы можем использовать переменные среды:

Мы можем предоставить столько переменных среды, сколько захотим, в строковом массиве. Здесь мы только что напечатали значение var1 , используя echo .

Выполнение этого кода вернет:

Запуск файлов .bat и .sh

Иногда просто гораздо проще выгрузить все в файл и запустить этот файл вместо того, чтобы добавлять все программно.

В зависимости от вашей операционной системы вы будете использовать файлы .bat или|/. sh|/. Давайте создадим его с содержимым:

Git Essentials

Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!

Тогда давайте воспользуемся тем же подходом, что и раньше:

Это откроет командную строку и запустит файл .bat в заданном нами рабочем каталоге.

Запуск этого кода, несомненно, приведет к:

Теперь, когда все перегруженные exec() подписи устранены, давайте рассмотрим класс ProcessBuilder и то, как мы можем выполнять команды с его помощью.

Конструктор процессов

ProcessBuilder является базовым механизмом, который выполняет команды при использовании метода Runtime.getRuntime().exec() :

JavaDocs для Время выполнения класс

Взглянув на то, как ProcessBuilder принимает наши входные данные из метода exec() и запускает команду, мы также получаем хорошее представление о том, как ее использовать.

Он принимает строку [] cmdarray , и этого достаточно, чтобы запустить его. В качестве альтернативы мы можем предоставить ему дополнительные аргументы, такие как String[] envp и File dir .

Давайте рассмотрим эти варианты.

ProcessBuilder: Выполнение команды из строк

Вместо того, чтобы предоставлять одну строку , такую как cmd/c dir , в этом случае нам придется разбить ее. Например, если бы мы хотели перечислить файлы в C:/Users каталог, как и раньше, мы бы сделали:

Чтобы фактически выполнить Процесс , мы запускаем команду start() и присваиваем возвращаемое значение экземпляру Процесса .

Запуск этого кода приведет к:

Однако этот подход ничем не лучше предыдущего. Что полезно в классе ProcessBuilder , так это то, что он настраивается. Мы можем устанавливать вещи программно, а не только с помощью команд.

ProcessBuilder: Укажите рабочий каталог

Вместо того, чтобы указывать рабочий каталог с помощью команды, давайте установим его программно:

Здесь мы установили рабочий каталог таким же, как и раньше, но мы удалили это определение из самой команды. Выполнение этого кода даст тот же результат, что и в предыдущем примере.

ProcessBuilder: Переменные среды

Используя методы ProcessBuilder , легко получить список переменных среды в виде Карты . Также легко установить переменные среды, чтобы ваша программа могла их использовать.

Давайте получим переменные среды, доступные в настоящее время, а затем добавим некоторые для последующего использования:

Здесь мы упаковали возвращенные переменные среды в Map и запустили forEach() на нем, чтобы распечатать значения на нашей консоли.

Выполнение этого кода приведет к получению списка переменных среды, имеющихся на вашем компьютере:

Теперь давайте добавим переменную среды в этот список и будем использовать ее:

Запуск этого кода приведет к:

Конечно, как только программа завершит работу, эта переменная не останется в списке.

ProcessBuilder: Запуск файлов .bat и .sh

Если вы хотите снова запустить файл, мы просто предоставим экземпляру ProcessBuilder необходимую информацию:

Выполнение этого кода приводит к открытию командной строки и выполнению файла .bat .:

Вывод

В этой статье мы рассмотрели примеры выполнения команд оболочки на Java. Для этого мы использовали классы Runtime и ProcessBuilder .

Используя Java, мы можем запускать одну или несколько команд оболочки, выполнять сценарии оболочки, запускать терминал/командную строку, устанавливать рабочие каталоги и управлять переменными среды с помощью основных классов.

Читайте также:  Как сбросить показатель чернил на принтере canon

Источник

Как с помощью Java выполнить Shell-команду

Обзор

В этом руководстве мы рассмотрим два способа выполнения shell -команд из программы на Java . Первый способ – использовать класс Runtime и вызвать его метод exec . Второй (более гибкий способ) – создать экземпляр класса ProcessBuilder .

Зависимость операционной системы

Сначала нужно определить операционную систему, на которой работает наша JVM . В Windows необходимо запустить команду в качестве аргумента оболочки cmd.exe, а в остальных ОС мы будем использовать стандартную оболочку sh:

Ввод и вывод

Также нужно подключиться к входным и выходным потокам нашего процесса. По крайней мере, нужно получить выходные данные, иначе процесс зависнет.

Реализуем класс StreamGobbler, который использует InputStream :

Примечание. Этот класс реализует интерфейс Runnable , а это означает, что он может быть выполнен любым исполнителем.

Runtime.exec()

Метод Runtime.exec() — это простой, но недостаточно гибкий способ создания нового подпроцесса .

В следующем примере мы запросим список пользователей из локальной директории и выведем его в консоли:

ProcessBuilder

Класс ProcessBuilder является более гибким в использовании, чем Runtime. Он позволяет настраивать целый ряд параметров.

  • изменить рабочий каталог, в котором работает shell-команда,
  • перенаправить потоки ввода и вывода;
  • наследовать их в потоках текущего процесса JVM, используя builder.inheritIO().

Заключение

Shell команды в Java можно выполнять двумя различными способами. Но если нужно настроить выполнение созданного процесса, то используйте класс ProcessBuilder .

Программные исходники примеров, приведенных в этой статье, доступны на GitHub .

Вадим Дворников автор-переводчик статьи « How to Run a Shell Command in Java »

Источник

Выполнение консольной команды в java se

подскажите как с помощью java se можно выполнить консольную команду: useradd -m -g papka -p 123456 sky

Сможете показать пример. а то чет разобраться не могу.

Копайте в сторону java.lang.ProcessBuilder.

Спасибо) теперь разобрался вроде бы)

вообще, толку от такого запуска 0, вдруг там попросят пароль ввести или нафиг пошлют, а ты сидишь и ждешь waitFor

Ну это джава же. Ждать когда она пролагается — единственный сценарий ее использования.

можно запустить процесс в жавном эмуляторе терминала, парсить выхлоп и expect’ом ждать всё что нужно

Источник

Русские Блоги

Java-программа выполняет команды Linux

Выполнение команд linux в программах Java в основном зависит от двух категорий: Process и Runtime

Сначала посмотрите на класс Process:

  1. Методы ProcessBuilder.start () и Runtime.exec создают собственный процесс и возвращают экземпляр подкласса Process.
  2. Этот экземпляр можно использовать для управления процессом и получения соответствующей информации. Категория «Процесс» обеспечивает выполнение от ввода процесса, вывод выполнения до процесса, ожидание завершения процесса,
  3. Проверьте состояние выхода процесса и как уничтожить (убить) процесс. к
  4. Метод создания процесса может не работать для определенных процессов на некоторых собственных платформах, таких как процессы собственного окна, процессы демона, Microsoft Windows
  5. Процесс Win16 / DOS или скрипт оболочки на предыдущей странице. Созданный дочерний процесс не имеет собственного терминала или консоли. Все его стандарты io (т.е. stdin, stdout и stderr)
  6. Операции будут перенаправлены в родительский процесс через три потока (getOutputStream (), getInputStream () и getErrorStream ()). к
  7. Родительский процесс использует эти потоки для предоставления входных данных дочернему процессу и получения выходных данных дочернего процесса. Поскольку некоторые собственные платформы предоставляют ограниченный размер буфера для стандартных входных и выходных потоков,
  8. Если выходной поток или входной поток дочернего процесса чтения и записи завершается неудачно, это может привести к блокировке дочернего процесса или даже к возникновению взаимоблокировки. к
  9. Когда больше нет ссылок на объект Process, вместо удаления дочернего процесса он продолжает выполнять дочерний процесс асинхронно. к
  10. Для процесса Java с объектом Process нет необходимости выполнять процесс, представленный объектом Process, асинхронно или одновременно. к

Особое внимание следует уделить:

1, Созданный дочерний процесс не имеет собственной терминальной консоли Все операции по маркировке будут проходить через три потока.

(getOutputStream (), getInputStream () и getErrorStream ()) перенаправляют в родительский процесс ( Родительский процесс может судить о выполнении дочернего процесса через эти потоки. )

2. Потому что Некоторые собственные платформы предоставляют ограниченный размер буфера для стандартных потоков ввода и вывода Если выходной поток или входной поток для чтения и записи дочернего процесса завершается неудачно,

Читайте также:  Chrome или chromium linux

Это может привести к блокировке дочернего процесса или даже к тупику

  1. abstract void destroy()
  2. Убей дочерний процесс. .
  3. abstract int exitValue()
  4. Вернуть значение экспорта дочернего процесса. По соглашению, значение 0 означает нормальное завершение. .
  5. abstract InputStream getErrorStream()
  6. Получите поток ошибок дочернего процесса. .
  7. abstract InputStream getInputStream()
  8. Получите входной поток дочернего процесса. .
  9. abstract OutputStream getOutputStream()
  10. Получите выходной поток дочернего процесса. .
  11. abstract int waitFor()
  12. Это заставляет текущий поток ждать. При необходимости он должен ждать, пока процесс, представленный объектом Process, не завершится. к
  13. Если дочерний процесс был завершен, этот метод немедленно возвращается. Если дочерний процесс не завершен, вызывающий поток будет заблокирован до завершения дочернего процесса. к

Особое внимание следует уделить: если во входном потоке, выходном потоке или потоке ошибок в дочернем процессе больше содержимого, лучше использовать кэш (Обратите внимание на ситуацию 2 выше)

Давайте снова посмотрим на класс Runtime:

  1. Каждое Java-приложение имеет экземпляр класса Runtime, который позволяет приложению подключаться к среде, в которой оно выполняется. Текущую среду выполнения можно получить с помощью метода getRuntime. .
  2. Приложение не может создать свой собственный экземпляр класса Runtime. .

Введите несколько основных методов:

  1. Process exec(String command)
  2. Выполнить указанную строковую команду в отдельном процессе. к
  3. Process exec(String command, String[] envp)
  4. Выполните указанную строковую команду в отдельном процессе в указанной среде. к
  5. Process exec(String command, String[] envp, File dir)
  6. Выполните указанную строковую команду в независимом процессе с указанной средой и рабочим каталогом. к
  7. Process exec(String[] cmdarray)
  8. Выполните назначенные команды и переменные в отдельном процессе. .
  9. Process exec(String[] cmdarray, String[] envp)
  10. Выполнять назначенные команды и переменные в независимом процессе в назначенной среде. .
  11. Process exec(String[] cmdarray, String[] envp, File dir)
  12. Выполните указанные команды и переменные в независимом процессе указанной среды и рабочего каталога. .

команда: указанная системная команда.

envp: Строковый массив переменных среды, где форматом установки каждой переменной среды является имя = значение; если дочерний процесс должен наследовать среду текущего процесса, этот параметр имеет значение null.

dir: рабочий каталог дочернего процесса, если дочерний процесс должен наследовать рабочий каталог текущего процесса, этот параметр имеет значение null.

cmdarray: массив, содержащий вызываемые команды и их параметры.

Ниже приведен пример (его нужно пометить как исполняемый пакет jar и выбросить под linux для выполнения):

  1. public class test <
  2. public static void main(String[] args) <
  3. InputStream in = null ;
  4. try <
  5. Process pro = Runtime.getRuntime().exec( new String[] < "sh" ,
  6. «/home/test/test.sh» , «select admin from M_ADMIN» ,
  7. «/home/test/result.txt» >);
  8. pro.waitFor();
  9. in = pro.getInputStream();
  10. BufferedReader read = new BufferedReader( new InputStreamReader(in));
  11. String result = read.readLine();
  12. System.out.println( «INFO:» +result);
  13. > catch (Exception e) <
  14. e.printStackTrace();
  15. >
  16. >
  17. >

Здесь используется метод Process exec (String [] cmdarray)

Сценарий /home/test/test.sh выглядит следующим образом:

  1. #!/bin/sh
  2. #Query sql
  3. SQL=$1
  4. # Запрос сохранить файл сохранения
  5. RESULT_FILE=$2
  6. # Подключение к базе данных
  7. DB_NAME=scott
  8. DB_PWD=tiger
  9. DB_SERVER=DB_TEST
  10. RESULT=`sqlplus -S $/$@$
  11. set heading off
  12. set echo off
  13. set pages 0
  14. set feed off
  15. set linesize 3000
  16. $
  17. /
  18. commit
  19. /
  20. !`
  21. echo «$» >> $
  22. echo 0;

Особое внимание следует обратить на тот факт, что когда выполняемая команда linux имеет символ канала (например, ps -ef | grep java), описанный выше метод не будет работать. Решение состоит в том, чтобы передать команду, которая будет выполнена, в качестве параметра оболочке

  1. public class Test <
  2. public static void main(String[] args) throws Exception <
  3. String[] cmds = < "/bin/sh" , "-c" , "ps -ef|grep java" >;
  4. Process pro = Runtime.getRuntime().exec(cmds);
  5. pro.waitFor();
  6. InputStream in = pro.getInputStream();
  7. BufferedReader read = new BufferedReader( new InputStreamReader(in));
  8. String line = null ;
  9. while ((line = read.readLine())!= null ) <
  10. System.out.println(line);
  11. >
  12. >
  13. >

Runtime.getRuntime (). Exec () очень ресурсоемкий в виртуальной машине Java. Даже если команда может быть выполнена быстро, создание процесса потребляет очень объективно во время частых вызовов.

Процесс выполнения этой команды в виртуальной машине Java, прежде всего, клон Процесс, имеющий те же переменные среды, что и текущая виртуальная машина, затем использует этот новый процесс для выполнения внешних команд и, наконец, завершает процесс. Частое создание потребляет много ресурсов процессора и памяти

Источник

Поделиться с друзьями
КомпСовет
Adblock
detector