Java как найти cmd

(as others said) For simple commands, you can just do, eg:
Runtime.getRuntime().exec("cmd /c mkdir H:\test\BBB");
(cmd /c is likely needed)

However, for some complex commands, you may need to do a double cmd.exe /c cmd.exe /c,
otherwise (if you use only 1) the cmd gets silently dropped,
((or if you dont use /c or use some weird /c cmd combination pattern, cmd may freeze)),
idk why.

((How I discorve it? — I couldnt get it work & tried mutiple time; one time accidentally duplicated the cmd & ran it & found it.))

@eg::

import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class T1 {

  static String convertStreamToString(java.io.InputStream is) {
    java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\A");
    return s.hasNext() ? s.next() : "";
  }

  public static void main(String[] args) throws InterruptedException, IOException {

    Process process;

    System.out.println("---"); // creates a folder `BBB`
    Runtime.getRuntime().exec("cmd /c mkdir H:\test\BBB");

    // System.out.println("---");
    // idk how to do `cd`

    System.out.println("---"); // list file & folder in C:
    process = Runtime.getRuntime().exec("cmd.exe /c dir C:\");
    System.out.println(convertStreamToString(process.getInputStream()));

    System.out.println("---"); // echo
    process = Runtime.getRuntime().exec("cmd.exe /c echo "Some Line"");
    System.out.println(convertStreamToString(process.getInputStream()));

    // @atten: notice the double `cmd.exe /c cmd.exe /c ` 
    // -- idk why must double - otherwise this wont execute
    System.out.println("---"); // uses mysqldump to do something 
    process = Runtime.getRuntime().exec("cmd.exe /c cmd.exe /c "C:\Program Files\MySQL\MySQL Server 8.0\bin\mysqldump.exe" -u root -pmysql db_drawandchat_01 > "H:\DrawAndChatApp_db\DrawAndChat_20230503_0134_03326.sql"");

  }

  // Output::
  //
  // ---
  // ---
  //  Volume in drive C has no label.
  //  Volume Serial Number is 2C83-063F
  // 
  //  Directory of C:
  // 
  // 2019/06/29  11:56    <DIR>          Intel
  // 2022/04/18  06:07    <DIR>          log
  // 2019/12/07  17:14    <DIR>          PerfLogs
  // 2023/04/22  01:13    <DIR>          Program Files
  // 2023/04/08  21:27    <DIR>          Program Files (x86)
  // 2020/12/08  00:15    <DIR>          Untitled
  // 2021/04/23  04:57    <DIR>          Users
  // 2023/04/25  09:33    <DIR>          Windows
  //                0 File(s)              0 bytes
  //                8 Dir(s)   3,268,296,704 bytes free
  // 
  // ---
  // "Some Line"
  // 
  // ---

}


update

base on my experience

ProcessBuilder with array of String as args is a much better choice.

@note::

  • use array of String as args, dont use a whole String
    otherwise the parsing is likely to be wrong.
    CreateProcess error=2, The system cannot find the file specified

  • remove unnecessary double quotes (eg: the ones around a path of a exec)
    (since you are using array, the space_in_path cmd problem is kinda eliminated // actually, not really, see update below -> still use [a double cmd.exe /c cmd.exe /c]).
    Java — ProcessBuilder command arguments with spaces and double-quotes fails

  • the array is separated base on the «exec & flag & arg & path»
    — normally, wherever you have a space, you separate there (though, not on the paths)

    • sometimes you dont separate the flag and arg (if there is no space between them), eg: -pPASSWORD

@eg:: [String Cmd to Array Cmd in ProcessBuilder]

(following code worked before, but didnt test after some minor modifications)

  public class T1 {

    public static void main(String[] args) throws InterruptedException, IOException {

      String cmdStr_loadFile = "cmd.exe /c cmd.exe /c "
                               + ""C:\Program Files\MySQL\MySQL Server 8.0\bin\mysql.exe" "
                               + "-u root "
                               + "-pmysql "
                               + "--database db_drawandchat_02 "
                               + "< "
                               + ""H:\DrawAndChatApp_db\DrawAndChat_test.sql"";

      ArrayList<String> cmdArr_loadFile = new ArrayList<>(Arrays.asList("cmd", "/c",
          "C:\Program Files\MySQL\MySQL Server 8.0\bin\mysql.exe",
          "-u", "root",
          "-pmysql",
          "--database", "db_drawandchat_02",
          "<",
          "H:\DrawAndChatApp_db\DrawAndChat_test.sql"));

      try {
        //      Process process = Runtime.getRuntime().exec(cmdStr_loadFile);

        ProcessBuilder processBuilder = new ProcessBuilder(cmdArr_loadFile);
        //      processBuilder.directory(new File("H:/"));
        processBuilder.redirectOutput(Redirect.INHERIT);
        processBuilder.redirectError(Redirect.INHERIT);
        //      processBuilder.redirectInput(Redirect.INHERIT);

        Process process = processBuilder.start();

        try {
          process.waitFor(20, TimeUnit.SECONDS);
          //        System.out.println(StringUtil.convertStreamToString(process.getInputStream()));
        } catch (InterruptedException e) {
          throw new Error(e);
        }
      } catch (IOException e) {
        throw new Error(e);
      }
    }

  }

update

The use of >»a double cmd.exe /c cmd.exe /c»
is also working in the case of >»ProcessBuilder with array of String as args«

Especially when you have space in your path — both executable path && file path arg

@eg::

    ArrayList<String> cmdArr_saveFile = new ArrayList<>(
        Arrays.asList("cmd", "/c", "cmd", "/c",
                      "C:\Program Files\MySQL\MySQL Server 8.0\bin\mysqldump.exe",
                      "-u", "root",
                      "-pmysql",
                      "db_drawandchat_01",
                      ">",
                      "H:\DrawAndChatApp_db\DrawAndChat test2.sql"));
  • However, if you have a space in your argument (not file path arg),
    it still wont work…
    related: java ProcessBuilder in Windows spaces in *.exe path and in argument

  • [[I do wonder why «double cmd.exe /c cmd.exe /c» works / how the Java Process cmd parsing really works.]]

Improve Article

Save Article

Like Article

  • Read
  • Discuss
  • Improve Article

    Save Article

    Like Article

    This article aims to provide you a simple code to open Command Prompt and how you can insert the commands in it using Java language.

    Here we will use Runtime class of java.lang Package. This class allows Java application to interfere with the environment in which it is running as each and every Java application has an instance of Runtime class. To perform the task, let us have a look at exec() method of Runtime class.

    java.lang.Runtime.exec(String command) : methods plays a major role in executing the specified string command.It executes the specified string command in a separate process.

    Syntax: 
    public Process exec(String command)
    Parameters : 
    command : specific command
    Returns :
    A new Process object for managing the subprocess
    Throws:
    SecurityException - If a security manager exists and its checkExec method doesn't 
    allow creation of the subprocess
    IOException - If an I/O error occurs
    NullPointerException - If command is null
    IllegalArgumentException - If command is empty
    

    How to run Command Prompt

    class NewClass

    {

        public static void main(String[] args)

        {

            try

            {

               Runtime.getRuntime().exec(new String[] {"cmd", "/K", "Start"});

            }

            catch (Exception e)

            {

                System.out.println("HEY Buddy ! U r Doing Something Wrong ");

                e.printStackTrace();

            }

        }

    }

    Note :
    This program won’t run on Online-IDE, so please run it on your system JAVA compiler and see the working.
    Output :

    Insert and run the command

    Using this code you can perform certain commands in cmd. Given program executes the “dir”( list all directories) and “ping”(test the ability of the source computer to reach a specified destination computer) command in cmd.

    class NewClass

    {

        public static void main(String[] args)

        {

            try

            

             Runtime.getRuntime().exec("cmd /c start cmd.exe /K "dir && ping localhost"");

            }

            catch (Exception e)

            {

                System.out.println("HEY Buddy ! U r Doing Something Wrong ");

                e.printStackTrace();

            }

        }

    }

    Note :
    This program won’t run on Online-IDE, so please run it on your system JAVA compiler and see the working.
    Output :

    This article is contributed by Mohit Gupta_OMG 😀. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

    Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

    Last Updated :
    19 Jun, 2017

    Like Article

    Save Article

    How to run command-line or execute external application from Java

    How to run command-line or execute external application from Java

    Have you ever confront a situation that you need to execute external programs while developing a Java application? For instance, you are developing a Java application and need to execute external application(another executable program) in the middle of the program or you may need to execute some commands such as listing directory command: dir (in windows) or ls (in Unix) while developing the program. The following will show you how to execute the external program from Java application.

    Example

    Note: The example will use NetBeans as IDE.

    Let see the example Java source code below:

     
    import java.io.*;
     
    public class Main {
     
           public static void main(String args[]) {
     
                try {
                    Runtime rt = Runtime.getRuntime();
                    //Process pr = rt.exec("cmd /c dir");
                    Process pr = rt.exec("c:\helloworld.exe");
     
                    BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()));
     
                    String line=null;
     
                    while((line=input.readLine()) != null) {
                        System.out.println(line);
                    }
     
                    int exitVal = pr.waitFor();
                    System.out.println("Exited with error code "+exitVal);
     
                } catch(Exception e) {
                    System.out.println(e.toString());
                    e.printStackTrace();
                }
            }
    }

    The above Java’s code will try to execute the external program (helloworld.exe) and show output in console as exit code of the external program.

    The sample external program, Helloworld.exe (Visual Basic)
    Visual Basic - Hello World

    Code Explanation:

    Runtime rt = Runtime.getRuntime();
    Process pr = rt.exec("c:\helloworld.exe");

    Create Runtime Object and attach to system process. In this example, execute the helloworld.exe.
    If you want to execute some commands, just modify the string in the rt.exec(“….�?) to command that you want.
    For instance, in the comment line; //Process pr = rt.exec(“cmd /c dir”);
    Note: that you need to enter “cmd /c …�? before type any command in Windows.

    int exitVal = pr.waitFor();
    System.out.println("Exited with error code "+exitVal);

    Method waitFor() will make the current thread to wait until the external program finish and return the exit value to the waited thread.

    Output example

    Process pr = rt.exec(“c:\helloworld.exe”);
    Execute external program with exit code

    Process pr = rt.exec(“cmd /c dir”);
    Execute windows command

    Summary

    This is a simple code to execute external applications. If you want to call functions from other program (ex. C++, Visual Basic DLL), you need to use JNI (Java Native Interface) which you can find a nice tutorial at codeproject.com.
    If you need more information, below are some sites that talk about executing external code.

    For Java users

    • Execute an external program – Real’s Java How-to.
      http://www.rgagnon.com/javadetails/java-0014.html
    • When Runtime.exec() won’t – Java World.
      http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html
    • Trouble with Runtime.getRuntime().exec(cmd) on Linux – Java.
      http://www.thescripts.com/forum/thread16788.html
    • Runtime.getRuntime().exec (Linux / UNIX forum at JavaRanch).
      http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=13&t=001755
    • Java’s Runtime.exec() and External Applications.
      http://www.ensta.fr/~diam/java/online/io/javazine.html

    For C++ users

    • How can I start a process?
      http://www.codeguru.com/forum/showthread.php?t=302501
    • Executing programs with C(Linux).
      http://www.gidforums.com/t-3369.html

    Вступление

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

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

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

    Runtime.exec ()

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

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

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

    • public Process exec(String command) — выполняет команду,
      содержащуюся в command в отдельном процессе.
    • public Process exec(String command, String[] envp) — выполняет
      command с массивом переменных среды. Они представлены в виде
      массива строк в формате name=value
    • public Process exec(String command, String[] envp, File dir)
      выполняет command с указанными переменными среды из каталога dir
    • public Process exec(String cmdArray[]) — выполняет команду в виде
      массива строк.
    • public Process exec(String cmdArray[], String[] envp) — выполняет
      команду с указанными переменными среды.
    • public Process exec(String cmdarray[], String[] envp, File dir)
      выполняет команду с указанными переменными среды из каталога dir

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

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

    Вам решать, что вы хотите использовать — exec("dir /folder") или
    exec(new String[]{"dir", "/folder"}

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

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

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

     Process process = Runtime.getRuntime().exec("ping www.stackabuse.com"); 
    

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

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

     public static void printResults(Process process) throws IOException { 
     BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); 
     String line = ""; 
     while ((line = reader.readLine()) != null) { 
     System.out.println(line); 
     } 
     } 
    

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

     Pinging www.stackabuse.com [104.18.57.23] with 32 bytes of data: 
     Reply from 104.18.57.23: bytes=32 time=21ms TTL=56 
     Reply from 104.18.57.23: bytes=32 time=21ms TTL=56 
     Reply from 104.18.57.23: bytes=32 time=21ms TTL=56 
     Reply from 104.18.57.23: bytes=32 time=21ms TTL=56 
     
     Ping statistics for 104.18.57.23: 
     Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), 
     Approximate round trip times in milli-seconds: 
     Minimum = 21ms, Maximum = 21ms, Average = 21ms 
    

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

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

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

     Process process = Runtime.getRuntime() 
     .exec("cmd /c dir", null, new File("C:\Users\")); 
     //.exec("sh -c ls", null, new File("Pathname")); for non-Windows users 
     printResults(process); 
    

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

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

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

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

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

     Volume in drive C has no label. 
     Volume Serial Number is XXXX-XXXX 
     
     Directory of C:Users 
     
     08/29/2019 05:01 PM <DIR> . 
     08/29/2019 05:01 PM <DIR> .. 
     08/18/2016 09:11 PM <DIR> Default.migrated 
     08/29/2019 05:01 PM <DIR> Public 
     05/15/2020 11:08 AM <DIR> User 
     0 File(s) 0 bytes 
     5 Dir(s) 212,555,214,848 bytes free 
    

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

     Process process = Runtime.getRuntime().exec( 
     new String[]{"cmd", "/c", "dir"}, 
     null, 
     new File("C:\Users\")); 
     
     printResults(process); 
    

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

     Volume in drive C has no label. 
     Volume Serial Number is XXXX-XXXX 
     
     Directory of C:Users 
     
     08/29/2019 05:01 PM <DIR> . 
     08/29/2019 05:01 PM <DIR> .. 
     08/18/2016 09:11 PM <DIR> Default.migrated 
     08/29/2019 05:01 PM <DIR> Public 
     05/15/2020 11:08 AM <DIR> User 
     0 File(s) 0 bytes 
     5 Dir(s) 212,542,808,064 bytes free 
    

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

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

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

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

     Process process = Runtime.getRuntime().exec( 
     "cmd /c echo %var1%", 
     new String[]{"var1=value1"}); 
     
     printResults(process); 
    

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

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

     value1 
    

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

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

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

     echo Hello World 
    

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

     Process process = Runtime.getRuntime().exec( 
     "cmd /c start file.bat", 
     null, 
     new File("C:\Users\User\Desktop\")); 
    

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

    Выполнение этого кода, безусловно, приведет к:

    командная строка с приветмиром{.ezlazyload}

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

    ProcessBuilder

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

     /** 
     * Executes the specified command and arguments in a separate process with 
     * the specified environment and working directory. 
     *... 
     */ 
     public Process exec(String[] cmdarray, String[] envp, File dir) throws IOException { 
     return new ProcessBuilder(cmdarray) 
     .environment(envp) 
     .directory(dir) 
     .start(); 
     } 
    

    [JavaDocs для класса Runtime]{.small}

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

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

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

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

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

     ProcessBuilder processBuilder = new ProcessBuilder(); 
     processBuilder.command("cmd", "/c", "dir C:\Users"); 
     
     Process process = processBuilder.start(); 
     printResults(process); 
    

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

    Запуск этого кода даст:

     Volume in drive C has no label. 
     Volume Serial Number is XXXX-XXXX 
     
     Directory of C:Users 
     
     08/29/2019 05:01 PM <DIR> . 
     08/29/2019 05:01 PM <DIR> .. 
     08/18/2016 09:11 PM <DIR> Default.migrated 
     08/29/2019 05:01 PM <DIR> Public 
     05/15/2020 11:08 AM <DIR> User 
     0 File(s) 0 bytes 
     5 Dir(s) 212,517,294,080 bytes free 
    

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

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

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

     processBuilder.command("cmd", "/c", "dir").directory(new File("C:\Users\")); 
    

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

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

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

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

     ProcessBuilder processBuilder = new ProcessBuilder(); 
     
     Map<String, String> environmentVariables = processBuilder.environment(); 
     environmentVariables.forEach((key, value) -> System.out.println(key + value)); 
    

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

    Запуск этого кода даст список переменных среды, которые есть на вашем
    компьютере:

     DriverDataC:WindowsSystem32DriversDriverData 
     HerokuPathE:Heroku 
     ProgramDataC:ProgramData 
     ... 
    

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

     environmentVariables.put("var1", "value1"); 
     
     processBuilder.command("cmd", "/c", "echo", "%var1%"); 
     Process process = processBuilder.start(); 
     printResults(process); 
    

    Запуск этого кода даст:

     value1 
    

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

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

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

     processBuilder 
     .command("cmd", "/c", "start", "file.bat") 
     .directory(new File("C:\Users\User\Desktop")); 
     Process process = processBuilder.start(); 
    

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

    командная строка привет мир batфайл{.ezlazyload}

    Заключение

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

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

    Introduction

    In this article, we’ll take a look at how we can leverage the Runtime and ProcessBuilder classes to execute shell commands and scripts with Java.

    We use computers to automate many things in our daily jobs. System administrators run many commands all the time, some of which are very repetitive and require minimal changes in-between runs.

    This process is also ripe for automation. There’s no need to run everything manually. Using Java, we can run single or multiple shell commands, execute shell scripts, run the terminal/command prompt, set working directories and manipulate environment variables through core classes.

    Runtime.exec()

    The Runtime class in Java is a high-level class, present in every single Java application. Through it, the application itself communicates with the environment it’s in.

    By extracting the runtime associated with our application via the getRuntime() method, we can use the exec() method to execute commands directly or run .bat/.sh files.

    The exec() method offers a few overloaded variations:

    • public Process exec(String command) — Executes the command contained in command in a separate process.
    • public Process exec(String command, String[] envp) — Executes the command, with an array of environment variables. They’re provided as an array of Strings, following the name=value format.
    • public Process exec(String command, String[] envp, File dir) — Executes the command, with the specified environment variables, from within the dir directory.
    • public Process exec(String cmdArray[]) — Executes a command in the form of an array of Strings.
    • public Process exec(String cmdArray[], String[] envp) — Executes a command with the specified environment variables.
    • public Process exec(String cmdarray[], String[] envp, File dir) — Executes a command, with the specified environment variables, from within the dir directory.

    It’s worth noting that these processes are run externally from the interpreter and will be system-dependent.

    What’s also worth noting is the difference between String command and String cmdArray[]. They achieve the same thing. A command is broken down into an array anyway, so using any of these two should yield the same results.

    It’s up to you to decide whether exec("dir /folder") or exec(new String[]{"dir", "/folder"} is what you’d like to use.

    Let’s write up a few examples to see how these overloaded methods differ from each other.

    Executing a Command from String

    Let’s start off with the simplest approach out of these three:

    Process process = Runtime.getRuntime().exec("ping www.stackabuse.com");
    

    Running this code will execute the command we’ve supplied in String format. However, we don’t see anything when we run this.

    To validate if this ran correctly, we’ll want to get ahold of the process object. Let’s use a BufferedReader to take a look at what’s going on:

    public static void printResults(Process process) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line = "";
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
    }
    

    Now, when we run this method after the exec() method, it should yield something along the lines of:

    Pinging www.stackabuse.com [104.18.57.23] with 32 bytes of data:
    Reply from 104.18.57.23: bytes=32 time=21ms TTL=56
    Reply from 104.18.57.23: bytes=32 time=21ms TTL=56
    Reply from 104.18.57.23: bytes=32 time=21ms TTL=56
    Reply from 104.18.57.23: bytes=32 time=21ms TTL=56
    
    Ping statistics for 104.18.57.23:
        Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
    Approximate round trip times in milli-seconds:
        Minimum = 21ms, Maximum = 21ms, Average = 21ms
    

    Keep in mind that we’ll have to extract the process information from the Process instances as we go through other examples.

    Specify the Working Directory

    If you’d like to run a command from, say, a certain folder, we’d do something along the lines of:

    Process process = Runtime.getRuntime()
            .exec("cmd /c dir", null, new File("C:\Users\"));
          //.exec("sh -c ls", null, new File("Pathname")); for non-Windows users
    printResults(process);
    

    Here, we’ve provided the exec() method with a command, a null for new environment variables and a new File() which is set as our working directory.

    The addition of cmd /c before a command such as dir is worth noting.

    Since I’m working on Windows, this opens up the cmd and /c carries out the subsequent command. In this case, it’s dir.

    The reason why this wasn’t mandatory for the ping example, but is mandatory for this example is nicely answered by an SO user.

    Running the previous piece of code will result in:

    Volume in drive C has no label.
     Volume Serial Number is XXXX-XXXX
    
     Directory of C:Users
    
    08/29/2019  05:01 PM    <DIR>          .
    08/29/2019  05:01 PM    <DIR>          ..
    08/18/2016  09:11 PM    <DIR>          Default.migrated
    08/29/2019  05:01 PM    <DIR>          Public
    05/15/2020  11:08 AM    <DIR>          User
                   0 File(s)              0 bytes
                   5 Dir(s)  212,555,214,848 bytes free
    

    Let’s take a look at how we could supply the previous command in several individual parts, instead of a single String:

    Process process = Runtime.getRuntime().exec(
            new String[]{"cmd", "/c", "dir"},
            null, 
            new File("C:\Users\"));
            
    printResults(process);
    

    Running this piece of code will also result in:

    Volume in drive C has no label.
     Volume Serial Number is XXXX-XXXX
    
     Directory of C:Users
    
    08/29/2019  05:01 PM    <DIR>          .
    08/29/2019  05:01 PM    <DIR>          ..
    08/18/2016  09:11 PM    <DIR>          Default.migrated
    08/29/2019  05:01 PM    <DIR>          Public
    05/15/2020  11:08 AM    <DIR>          User
                   0 File(s)              0 bytes
                   5 Dir(s)  212,542,808,064 bytes free
    

    Ultimately, regardless of the approach — using a single String or a String array, the command you input will always be broken down into an array before getting processed by underlying logic.

    Which one you’d like to use boils down just to which one you find more readable.

    Using Environment Variables

    Let’s take a look at how we can use environment variables:

    Process process = Runtime.getRuntime().exec(
            "cmd /c echo %var1%",
            new String[]{"var1=value1"});
            
    printResults(process);
    

    We can supply as many environment variables as we’d like within the String array. Here, we’ve just printed the value of var1 using echo.

    Running this code will return:

    Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!

    value1
    

    Running .bat and .sh Files

    Sometimes, it’s just much easier to offload everything into a file and run that file instead of adding everything programmatically.

    Depending on your operating system, you’d use either .bat or .sh files. Let’s create one with the contents:

    echo Hello World
    

    Then, let’s use the same approach as before:

    Process process = Runtime.getRuntime().exec(
            "cmd /c start file.bat",
            null,
            new File("C:\Users\User\Desktop\"));
    

    This’ll open up the command prompt and run the .bat file in the working directory we’ve set.

    Running this code surely enough results in:

    With all of the overloaded exec() signatures taken care of, let’s take a look at the ProcessBuilder class and how we can execute commands using it.

    ProcessBuilder

    ProcessBuilder is the underlying mechanism that runs the commands when we use the Runtime.getRuntime().exec() method:

    /**
     * Executes the specified command and arguments in a separate process with
     * the specified environment and working directory.
     *...
    */
    public Process exec(String[] cmdarray, String[] envp, File dir) throws IOException {
        return new ProcessBuilder(cmdarray)
            .environment(envp)
            .directory(dir)
            .start();
    }
    

    JavaDocs for the Runtime class

    Taking a look at how the ProcessBuilder takes our input from the exec() method and runs the command, gives us a good idea of how to use it as well.

    It accepts a String[] cmdarray, and that’s enough to get it running. Alternatively, we can supply it with optional arguments such as the String[] envp and File dir.

    Let’s explore these options.

    ProcessBuilder: Executing Command from Strings

    Instead of being able to provide a single String, such as cmd /c dir, we’ll have to break it up in this case. For example, if we wanted to list the files in the C:/Users directory like before, we’d do:

    ProcessBuilder processBuilder = new ProcessBuilder();
    processBuilder.command("cmd", "/c", "dir C:\Users");
    
    Process process = processBuilder.start();
    printResults(process);
    

    To actually execute a Process, we run the start() command and assign the returned value to a Process instance.

    Running this code will yield:

     Volume in drive C has no label.
     Volume Serial Number is XXXX-XXXX
    
     Directory of C:Users
    
    08/29/2019  05:01 PM    <DIR>          .
    08/29/2019  05:01 PM    <DIR>          ..
    08/18/2016  09:11 PM    <DIR>          Default.migrated
    08/29/2019  05:01 PM    <DIR>          Public
    05/15/2020  11:08 AM    <DIR>          User
                   0 File(s)              0 bytes
                   5 Dir(s)  212,517,294,080 bytes free
    

    However, this approach isn’t any better than the previous one. What’s useful with the ProcessBuilder class is that it’s customizable. We can set things programmatically, not just via commands.

    ProcessBuilder: Specify the Working Directory

    Instead of supplying the working directory via the command, let’s set it programmatically:

    processBuilder.command("cmd", "/c", "dir").directory(new File("C:\Users\"));
    

    Here, we’ve set the working directory to be the same as before, but we’ve moved that definition out of the command itself. Running this code will provide the same result as the last example.

    ProcessBuilder: Environment Variables

    Using ProcessBuilders methods, it’s easy to retrieve a list of environment variables in the form of a Map. It’s also easy to set environment variables so that your program can use them.

    Let’s get the environment variables currently available and then add some for later use:

    ProcessBuilder processBuilder = new ProcessBuilder();
    
    Map<String, String> environmentVariables  = processBuilder.environment();
    environmentVariables.forEach((key, value) -> System.out.println(key + value));
    

    Here, we’ve packed the returned environment variables into a Map and ran a forEach() on it to print out the values to our console.

    Running this code will yield a list of the environment variables you have on your machine:

    DriverDataC:WindowsSystem32DriversDriverData
    HerokuPathE:Heroku
    ProgramDataC:ProgramData
    ...
    

    Now, let’s add an environment variable to that list and use it:

    environmentVariables.put("var1", "value1");
    
    processBuilder.command("cmd", "/c", "echo", "%var1%");
    Process process = processBuilder.start();
    printResults(process);
    

    Running this code will yield:

    value1
    

    Of course, once the program has finished running, this variable will not stay in the list.

    ProcessBuilder: Running .bat and .sh Files

    If you’d like to run a file, again, we’d just supply the ProcessBuilder instance with the required information:

    processBuilder
            .command("cmd", "/c", "start", "file.bat")
            .directory(new File("C:\Users\User\Desktop"));
    Process process = processBuilder.start();
    

    Running this code results in the command prompt opening up and executing the .bat file:

    Conclusion

    In this article, we’ve explored examples of running shell commands in Java. We’ve used the Runtime and ProcessBuilder classes to do this.

    Using Java, we can run single or multiple shell commands, execute shell scripts, run the terminal/command prompt, set working directories and manipulate environment variables through core classes.

    Понравилась статья? Поделить с друзьями:
  • Как найти готовые комнаты в симс
  • Как найти пропавшие фотографии с телефона
  • Как найти личное дело в военкомате
  • Как составить текст перевода земель
  • Найдите муху brain out как пройти