- Details
- Written by
- Last Updated on 27 July 2019 | Print Email
This Java File IO tutorial guides you how to write Java code to run native commands of the host operating system.
Although Java is a cross-platform programming language, sometimes we need to access to something in an operating system dependent way. In other words, we need a Java program to call native commands that are specific to a platform (Windows, Mac or Linux). For example, querying hardware information such as processer ID or hard disk ID requires invoking a kind of native command provided by the operating system. Throughout this tutorial, you will learn how to execute a native command from within a Java program, including sending inputs to and getting outputs from the command.
Basically, to execute a system command, pass the command string to the exec() method of the Runtime class. The exec() method returns a Process object that abstracts a separate process executing the command. From the Process object we can get outputs from and send inputs to the command. The following code snippet explains the principle:
String command = "command of the operating system"; Process process = Runtime.getRuntime().exec(command); // deal with OutputStream to send inputs process.getOutputStream(); // deal with InputStream to get ordinary outputs process.getInputStream(); // deal with ErrorStream to get error outputs process.getErrorStream();
Now, let’s walk through some real code examples.
The following code snippet runs the ping command on Windows and captures its output:
String command = "ping www.codejava.net"; try { Process process = Runtime.getRuntime().exec(command); BufferedReader reader = new BufferedReader( new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } reader.close(); } catch (IOException e) { e.printStackTrace(); }
It gives the following output in the standard console:
Pinging codejava.net [198.57.151.22] with 32 bytes of data: Reply from 198.57.151.22: bytes=32 time=227ms TTL=51 Reply from 198.57.151.22: bytes=32 time=221ms TTL=51 Reply from 198.57.151.22: bytes=32 time=220ms TTL=51 Reply from 198.57.151.22: bytes=32 time=217ms TTL=51 Ping statistics for 198.57.151.22: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 217ms, Maximum = 227ms, Average = 221ms
1. Getting Standard Output
For system commands that produce some output as result, we need to capture the output by creating a BufferedReader that wraps the InputStream returned from the Process:
BufferedReader reader = new BufferedReader( new InputStreamReader(process.getInputStream()));
Then invoke the readLine() method of the reader to read the output line by line, sequentially:
String line; while ((line = reader.readLine()) != null) { System.out.println(line); } reader.close();
We can also use a Scanner to read the command’s output, for example:
Scanner scanner = new Scanner(process.getInputStream()); scanner.useDelimiter("\r\n"); while (scanner.hasNext()) { System.out.println(scanner.next()); } scanner.close();
2. Getting Error Output
A command is not always executed successfully, because there would be a case in which the command encounters an error. And typically, error messages are sent to the error stream. The following code snippet captures the error input stream returned by the Process:
BufferedReader errorReader = new BufferedReader( new InputStreamReader(process.getErrorStream())); while ((line = errorReader.readLine()) != null) { System.out.println(line); } errorReader.close();
So it’s recommended to capture both the standard output and error output to handle both normal and abnormal cases.
3. Sending Input
For interactive system commands which need inputs, we can feed the inputs for the command by obtaining the OutputStream returned by the Process. For example, the following code snippet attempts to change system date on Windows to 09-20-14 (in mm-dd-yy format):
String command = "cmd /c date"; try { Process process = Runtime.getRuntime().exec(command); BufferedWriter writer = new BufferedWriter( new OutputStreamWriter(process.getOutputStream())); writer.write("09-20-14"); writer.close(); BufferedReader reader = new BufferedReader(new InputStreamReader( process.getInputStream())); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } reader.close(); } catch (IOException e) { e.printStackTrace(); }
Output:
The current date is: Sat 09/20/2014 Enter the new date: (mm-dd-yy) 09-20-14
Check the system clock, it is updated immediately.
4. Waiting for the process to terminate
For long-running command (e.g. batch script), we can make the calling thread to wait until the process has terminated, by invoking the waitFor() method on the Process object. For example:
int exitValue = process.waitFor(); if (exitValue != 0) { System.out.println("Abnormal process termination"); }
Note that the waitFor() method returns an integer value indicating whether the process terminates normally (value 0) or not. So it’s necessary to check this value.
5. Destroying the process and checking exit value
It’s recommend to destroy the process and checking its exit value to make sure the system command’s process is executed successfully and exited normally. For example:
process.destroy(); if (process.exitValue() != 0) { System.out.println("Abnormal process termination"); }
NOTE: Using the waitFor() and exitValue() method is exclusive, meaning that either one is used, not both.
6. Other exec() methods
Beside the primarily used method exec(Stringcommand), the Runtime class also has several overloaded ones. Notably this one:
exec(String[] cmdarray)
This method is useful to execute a command with several arguments, especially arguments contain spaces. For example, the following statements execute a Windows command to list content of the Program Files directory:
String commandArray[] = {"cmd", "/c", "dir", "C:\\Program Files"}; Process process = Runtime.getRuntime().exec(commandArray);
For other exec() methods, consult the relevant Javadoc which is listed below.
API References:
- Runtime class Javadoc
- Process class Javadoc
Other Java File IO Tutorials:
- How to Read and Write Text File in Java
- How to Read and Write Binary Files in Java
- Java IO — Common File and Directory Operations Examples
- Java Serialization Basic Example
- Understanding Java Externalization with Examples
- How to compress files in ZIP format in Java
- How to extract ZIP file in Java
- Java File change notification example with Watch Service API
About the Author:
Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.
Add comment
В этом руководстве мы рассмотрим два способа выполнения shell -команд из программы на Java . Первый способ – использовать класс Runtime и вызвать его метод exec. Второй (более гибкий способ) – создать экземпляр класса ProcessBuilder.
- Зависимость операционной системы
- Ввод и вывод
- Runtime.exec()
- ProcessBuilder
- Заключение
Сначала нужно определить операционную систему, на которой работает наша JVM . В Windows необходимо запустить команду в качестве аргумента оболочки cmd.exe, а в остальных ОС мы будем использовать стандартную оболочку sh:
boolean isWindows = System.getProperty("os.name") .toLowerCase().startsWith("windows");
Также нужно подключиться к входным и выходным потокам нашего процесса. По крайней мере, нужно получить выходные данные, иначе процесс зависнет.
Реализуем класс StreamGobbler, который использует InputStream:
private static class StreamGobbler implements Runnable { private InputStream inputStream; private Consumer<String> consumer; public StreamGobbler(InputStream inputStream, Consumer<String> consumer) { this.inputStream = inputStream; this.consumer = consumer; } @Override public void run() { new BufferedReader(new InputStreamReader(inputStream)).lines() .forEach(consumer); } }
Примечание. Этот класс реализует интерфейс Runnable, а это означает, что он может быть выполнен любым исполнителем.
Метод Runtime.exec() — это простой, но недостаточно гибкий способ создания нового подпроцесса.
В следующем примере мы запросим список пользователей из локальной директории и выведем его в консоли:
String homeDirectory = System.getProperty("user.home"); Process process; if (isWindows) { process = Runtime.getRuntime() .exec(String.format("cmd.exe /c dir %s", homeDirectory)); } else { process = Runtime.getRuntime() .exec(String.format("sh -c ls %s", homeDirectory)); } StreamGobbler streamGobbler = new StreamGobbler(process.getInputStream(), System.out::println); Executors.newSingleThreadExecutor().submit(streamGobbler); int exitCode = process.waitFor(); assert exitCode == 0;
Класс ProcessBuilder является более гибким в использовании, чем Runtime. Он позволяет настраивать целый ряд параметров.
Например, можно:
- изменить рабочий каталог, в котором работает shell-команда,
- перенаправить потоки ввода и вывода;
- наследовать их в потоках текущего процесса JVM, используя builder.inheritIO().
ProcessBuilder builder = new ProcessBuilder(); if (isWindows) { builder.command("cmd.exe", "/c", "dir"); } else { builder.command("sh", "-c", "ls"); } builder.directory(new File(System.getProperty("user.home"))); Process process = builder.start(); StreamGobbler streamGobbler = new StreamGobbler(process.getInputStream(), System.out::println); Executors.newSingleThreadExecutor().submit(streamGobbler); int exitCode = process.waitFor(); assert exitCode == 0;
Shell команды в Java можно выполнять двумя различными способами. Но если нужно настроить выполнение созданного процесса, то используйте класс ProcessBuilder.
Программные исходники примеров, приведенных в этой статье, доступны на GitHub .
Вадим Дворниковавтор-переводчик статьи «How to Run a Shell Command in Java»
Executing a system command
is relatively simple – once you’ve seen it done the first time.
It involves the use of two Java classes, the Runtime class and the Process class. Basically, you use the exec method
of the Runtime class to run the command as a separate process.
Invoking the exec method returns a Process object for managing the subprocess. Then you use the getInputStream()
and getErrorStream()
methods of the Process
object to read the normal output of the command, and the error output of the command. What you do with the output of the command executed is entirely up to you and the application you’re creating.
The ProcessBuilder.start()
and Runtime.exec
methods create a native process and return an instance of a subclass of Process
that can be used to control the process and obtain information about it.
The class Process
provides methods for performing input from the process, performing output to the process, waiting for the process to complete, checking the exit status of the process, and destroying (killing) the process.
The methods that create processes may not work well for special processes on certain native platforms, such as native windowing processes, daemon processes, Win16/DOS processes on Microsoft Windows, or shell scripts.
By default, the created subprocess does not have its own terminal or console. All its standard I/O (i.e. stdin, stdout, stderr) operations will be redirected to the parent process, where they can be accessed via the streams obtained using the methods getOutputStream()
, getInputStream()
, and getErrorStream()
.
The parent process uses these streams to feed input to and get output from the subprocess. Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, or even deadlock.
Below are two simple Java Examples for your reference.
Example-1. Execute mkdir, ls -ltra and ping in Java
- Create file CrunchifyCommandJava.java
- Execute
mkdir /Users/ashah/Desktop/new-folder
- Execute
ls -ltra /Library
- Execute
ping crunchify.com
package crunchify.com.tutorials; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; /** * @author Crunchify.com * Execute Linux commands using Java. We are executing mkdir, ls -ltra and ping in this tutorial */ public class CrunchifyCommandJava { public printOutput getStreamWrapper(InputStream is, String type) { return new printOutput(is, type); } public static void main(String[] args) { Runtime rt = Runtime.getRuntime(); CrunchifyCommandJava rte = new CrunchifyCommandJava(); printOutput errorReported, outputMessage; try { Process proc = rt.exec("mkdir /Users/ashah/Desktop/new-folder"); errorReported = rte.getStreamWrapper(proc.getErrorStream(), "ERROR"); outputMessage = rte.getStreamWrapper(proc.getInputStream(), "OUTPUT"); errorReported.start(); outputMessage.start(); } catch (IOException e) { e.printStackTrace(); } try { Process proc = rt.exec("ls -ltra /Library"); errorReported = rte.getStreamWrapper(proc.getErrorStream(), "ERROR"); outputMessage = rte.getStreamWrapper(proc.getInputStream(), "OUTPUT"); errorReported.start(); outputMessage.start(); } catch (IOException e) { e.printStackTrace(); } try { Process proc = rt.exec("ping crunchify.com"); errorReported = rte.getStreamWrapper(proc.getErrorStream(), "ERROR"); outputMessage = rte.getStreamWrapper(proc.getInputStream(), "OUTPUT"); errorReported.start(); outputMessage.start(); } catch (IOException e) { e.printStackTrace(); } } private class printOutput extends Thread { InputStream is = null; printOutput(InputStream is, String type) { this.is = is; } public void run() { String s = null; try { BufferedReader br = new BufferedReader( new InputStreamReader(is)); while ((s = br.readLine()) != null) { System.out.println(s); } } catch (IOException ioe) { ioe.printStackTrace(); } } } }
Make sure to change path accordingly in above program as per your system settings.
Eclipse console Output:
Just run above program as a Java Application and you will see similar result.
mkdir: /Users/ashah/Desktop/new-file-created.txt: File created total 0 drwxr-xr-x 3 root wheel 96 Aug 17 2018 Compositions drwxr-xr-x@ 2 root wheel 64 Aug 17 2018 GPUBundles drwxr-xr-x 2 root wheel 64 Aug 17 2018 SystemProfiler drwxr-xr-x 2 root wheel 64 Aug 17 2018 ColorPickers -rw-r--r-- 1 root wheel 0 Aug 17 2018 .localized drwxr-xr-x 2 root wheel 64 Aug 17 2018 StartupItems drwxr-xr-x 3 root wheel 96 Aug 17 2018 Speech drwxr-xr-x 4 root wheel 128 Aug 17 2018 Ruby drwxr-xr-x@ 2 root wheel 64 Aug 17 2018 CoreAnalytics drwxr-xr-x 3 root wheel 96 Aug 17 2018 DirectoryServices drwxr-xr-x 5 root wheel 160 Aug 17 2018 WebServer drwxr-xr-x 3 root wheel 96 Aug 17 2018 Perl drwxr-xr-x 2 root wheel 64 Aug 17 2018 ScriptingAdditions drwxr-xr-x 2 root wheel 64 Aug 17 2018 Keyboard Layouts drwxr-xr-x 3 root wheel 96 Aug 17 2018 Graphics drwxr-xr-x 3 root wheel 96 Aug 17 2018 Python drwxr-xr-x 8 root wheel 256 Oct 11 16:51 User Pictures drwxr-xr-x 3 root wheel 96 Oct 11 16:51 Screen Savers drwxr-xr-x 51 root wheel 1632 Oct 11 16:51 Desktop Pictures drwxr-xr-x 2 root wheel 64 Oct 18 18:51 Contextual Menu Items drwxr-xr-x 2 root wheel 64 Oct 18 18:51 Components drwxr-xr-x 5 root wheel 160 Oct 21 16:03 OpenDirectory drwxr-xr-x 2 root wheel 64 Oct 23 20:43 Input Methods drwxr-xr-x 4 root wheel 128 Oct 29 23:49 Video drwxr-xr-x 3 root wheel 96 Nov 5 21:20 Messages drwxr-xr-x@ 3 root wheel 96 Nov 12 22:37 MessageTracer drwxr-xr-x 3 root wheel 96 Nov 12 22:55 CoreMediaIO drwxr-xr-x 3 root wheel 96 Nov 29 23:38 Sandbox drwxr-xr-x 3 root wheel 96 Nov 29 23:38 Filesystems drwxr-xr-x 8 root wheel 256 Nov 29 23:40 Image Capture drwxr-xr-x 4 root wheel 128 Nov 29 23:41 Java drwxr-xr-x 4 root wheel 128 Nov 29 23:41 QuickTime drwxr-xr-x 10 root wheel 320 Nov 29 23:45 Scripts drwxrwxr-t 182 root admin 5824 Nov 29 23:47 Fonts drwxr-xr-x 4 root wheel 128 Nov 29 23:49 QuickLook drwxr-xr-x 4 root wheel 128 Nov 29 23:49 Spotlight drwxr-xr-x 37 root wheel 1184 Nov 29 23:50 Modem Scripts drwxr-xr-x 4 root wheel 128 Feb 11 13:00 ColorSync drwxr-xr-x 4 root wheel 128 Feb 11 13:04 Security drwxr-xr-x 8 root wheel 256 Feb 11 13:04 PDF Services drwxr-xr-x 3 root wheel 96 Feb 11 13:05 Catacomb drwxr-xr-x 9 root wheel 288 Feb 11 13:05 Frameworks drwxr-xr-x 3 root wheel 96 Feb 11 13:05 Automator drwxr-xr-x 10 root wheel 320 Feb 11 13:05 Audio drwxr-xr-x 3 root wheel 96 Feb 11 13:05 Tanium drwxr-xr-x+ 68 root wheel 2176 Feb 11 13:05 . drwxr-xr-x 3 root admin 96 Feb 11 13:05 Developer drwxr-xr-x 8 root wheel 256 Feb 11 13:05 Documentation drwxr-xr-x 4 root wheel 128 Feb 11 13:05 DropboxHelperTools drwxrwxr-x 14 root admin 448 Feb 11 13:07 Receipts drwxr-xr-x 4 root wheel 128 Feb 11 13:07 SystemMigration drwxr-xr-x@ 4 root wheel 128 Feb 11 13:10 StagedExtensions drwxr-xr-x 14 root wheel 448 Feb 11 18:26 Widgets drwxr-xr-x 13 root wheel 416 Feb 11 18:26 Extensions drwxr-xr-x 29 root wheel 928 Feb 11 18:35 .. drwxr-xr-x 9 root wheel 288 Feb 17 12:38 Logs drwxrwxrwt 11 root admin 352 Feb 22 13:29 Caches drwxr-xr-x 11 root wheel 352 Feb 22 13:36 LaunchAgents drwxr-xr-x 2 root wheel 64 Feb 22 13:36 PreferencePanes drwxr-xr-x 9 root wheel 288 Feb 22 13:36 Internet Plug-Ins drwxr-xr-t 7 root wheel 224 Feb 22 13:36 PrivilegedHelperTools drwxr-xr-x 18 root wheel 576 Feb 22 13:36 LaunchDaemons drwxr-xr-x 25 root admin 800 Feb 22 16:03 Application Support dr-xr-xr-x 9 root wheel 288 Feb 25 10:24 Printers drwxr-xr-x@ 5 root wheel 160 Feb 25 10:24 Updates drwxr-xr-x 10 root wheel 320 Feb 25 14:12 Keychains drwxr-xr-x 25 root wheel 800 Feb 26 08:07 Managed Preferences drwxr-xr-x 67 root wheel 2144 Feb 26 08:07 Preferences PING crunchify.com (35.197.114.216): 56 data bytes 64 bytes from 35.197.114.216: icmp_seq=0 ttl=54 time=70.275 ms 64 bytes from 35.197.114.216: icmp_seq=1 ttl=54 time=73.876 ms 64 bytes from 35.197.114.216: icmp_seq=2 ttl=54 time=68.134 ms 64 bytes from 35.197.114.216: icmp_seq=3 ttl=54 time=75.951 ms 64 bytes from 35.197.114.216: icmp_seq=4 ttl=54 time=70.205 ms
Example-2.
- CrunchifyRunCommand.java
- Execute command
ps -few
to get list of all processes running on your system.
package crunchify.com.tutorials; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** * @author Crunchify.com * Execute ps -few command in Java to get list of all processes */ public class CrunchifyRunCommand { public static void main(String[] args) { String s = null; try { // Process provides control of native processes started by ProcessBuilder.start and Runtime.exec. // getRuntime() returns the runtime object associated with the current Java application. Process p = Runtime.getRuntime().exec("ps -few"); BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream())); BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream())); // read the output from the command System.out.println("Here is the standard output of the command:\n"); while ((s = stdInput.readLine()) != null) { System.out.println(s); } // read any errors from the attempted command System.out.println("Here is the standard error of the command (if any):\n"); while ((s = stdError.readLine()) != null) { System.out.println(s); } System.exit(0); } catch (IOException e) { System.out.println("exception happened - here's what I know: "); e.printStackTrace(); System.exit(-1); } } }
Eclipse console Output:
Here is the standard output of the command: UID PID PPID C STIME TTY TIME CMD 0 1 0 0 Fri09PM ?? 7:14.76 /sbin/launchd 0 44 1 0 Fri09PM ?? 0:09.67 /usr/sbin/syslogd 0 45 1 0 Fri09PM ?? 0:12.95 /usr/libexec/UserEventAgent (System) 0 49 1 0 Fri09PM ?? 0:04.41 /System/Library/PrivateFrameworks/Uninstall.framework/Resources/uninstalld 0 50 1 0 Fri09PM ?? 0:26.75 /usr/libexec/kextd 0 51 1 0 Fri09PM ?? 2:00.76 /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/FSEvents.framework/Versions/A/Support/fseventsd 0 53 1 0 Fri09PM ?? 4:16.25 /usr/local/jamf/bin/jamf launchDaemon -enforceRestrictions -monitorNetworkStateChanges 0 54 1 0 Fri09PM ?? 0:01.29 /System/Library/PrivateFrameworks/MediaRemote.framework/Support/mediaremoted 55 57 1 0 Fri09PM ?? 0:01.23 /System/Library/CoreServices/appleeventsd --server 0 58 1 0 Fri09PM ?? 4:21.14 /usr/sbin/systemstats --daemon 0 60 1 0 Fri09PM ?? 0:41.10 /usr/libexec/configd 0 61 1 0 Fri09PM ?? 1:03.98 /System/Library/CoreServices/powerd.bundle/powerd 0 62 1 0 Fri09PM ?? 0:00.89 /Library/Application Support/JAMF/Jamf.app/Contents/MacOS/JamfDaemon.app/Contents/MacOS/JamfDaemon 0 65 1 0 Fri09PM ?? 0:43.84 /usr/libexec/logd 0 66 1 0 Fri09PM ?? 0:00.02 /usr/libexec/keybagd -t 15 0 73 1 0 Fri09PM ?? 3:26.45 /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Support/mds 240 74 1 0 Fri09PM ?? 0:00.11 /System/Library/CoreServices/iconservicesd 0 75 1 0 Fri09PM ?? 0:03.39 /usr/libexec/diskarbitrationd 0 79 1 0 Fri09PM ?? 0:00.73 /System/Library/CoreServices/backupd.bundle/Contents/Resources/backupd-helper -launchd 0 80 1 0 Fri09PM ?? 0:03.84 /usr/libexec/coreduetd 0 84 1 0 Fri09PM ?? 2:30.59 /usr/libexec/opendirectoryd 0 85 1 0 Fri09PM ?? 0:17.45 /System/Library/PrivateFrameworks/ApplePushService.framework/apsd 0 86 1 0 Fri09PM ?? 0:00.67 /System/Library/PrivateFrameworks/Noticeboard.framework/Versions/A/Resources/nbstated 0 87 1 0 Fri09PM ?? 0:16.91 /System/Library/CoreServices/launchservicesd 266 88 1 0 Fri09PM ?? 0:06.48 /usr/libexec/timed 0 89 1 0 Fri09PM ?? 0:25.37 /usr/sbin/securityd -i 213 90 1 0 Fri09PM ?? 0:01.16 /System/Library/PrivateFrameworks/MobileDevice.framework/Versions/A/Resources/usbmuxd -launchd 205 92 1 0 Fri09PM ?? 0:59.64 /usr/libexec/locationd 0 94 1 0 Fri09PM ?? 0:00.08 autofsd 244 95 1 0 Fri09PM ?? 0:03.06 /usr/libexec/displaypolicyd -k 1 0 98 1 0 Fri09PM ?? 0:11.56 /usr/libexec/dasd 0 99 1 0 Fri09PM ?? 0:00.71 /System/Library/PrivateFrameworks/Heimdal.framework/Helpers/kdc 0 103 1 0 Fri09PM ?? 0:00.87 /Library/Tanium/TaniumClient/TaniumClient -d 110048994 104 1 0 Fri09PM ?? 0:34.02 /System/Library/CoreServices/loginwindow.app/Contents/MacOS/loginwindow console 0 105 1 0 Fri09PM ?? 0:00.76 /System/Library/CoreServices/logind 0 106 1 0 Fri09PM ?? 0:00.66 /System/Library/PrivateFrameworks/GenerationalStorage.framework/Versions/A/Support/revisiond 0 107 1 0 Fri09PM ?? 0:00.03 /usr/sbin/KernelEventAgent 0 109 1 0 Fri09PM ?? 1:58.55 /usr/sbin/bluetoothd 261 110 1 0 Fri09PM ?? 13:48.55 /usr/libexec/hidd 0 112 1 0 Fri09PM ?? 0:06.37 /usr/libexec/corebrightnessd --launchd 0 113 1 0 Fri09PM ?? 0:04.23 /usr/libexec/AirPlayXPCHelper 0 114 1 0 Fri09PM ?? 1:07.01 /usr/sbin/notifyd 241 116 1 0 Fri09PM ?? 0:11.70 /usr/sbin/distnoted daemon 0 119 1 0 Fri09PM ?? 0:03.99 /usr/libexec/amfid 0 123 1 0 Fri09PM ?? 0:09.47 /usr/libexec/syspolicyd 0 124 1 0 Fri09PM ?? 0:05.81 /System/Library/Frameworks/Security.framework/Versions/A/XPCServices/authd.xpc/Contents/MacOS/authd 0 142 1 0 Fri09PM ?? 1:31.63 /usr/sbin/cfprefsd daemon 0 143 1 0 Fri09PM ?? 0:23.54 /System/Library/CoreServices/coreservicesd 0 166 1 0 Fri09PM ?? 0:21.34 /System/Library/PrivateFrameworks/CoreDuetContext.framework/Resources/contextstored
These are some of the processes running on my MacBook Pro. There are quite a few more but pasted very few.
I hope this tutorial helps you run any linux, macOS terminal commands using simple Java program. Let me know for any questions.
If you liked this article, then please share it on social media. Have a question or suggestion? Please leave a comment to start the discussion.
Last Updated :
03 Mar, 2021
A shell command is a command that we can trigger using a keyboard and a command-line or a shell instead of a Graphical user interface. Usually, we would trigger shell commands manually. However, there can be instances where this needs to be done programmatically through Java.
Java provides support to run native shell commands with two classes: RunTime and ProcessBuilder. The main disadvantage of using these classes and running shell commands from inside a Java Program is Java loses its portability.
What does losing portability mean?
Java goes by the principle «compile once, run anywhere.» This means that a Java program written and compiled on one operating system can run on any other operating system without making any changes.
When we use either the ProcessBuilder or the Runtime classes to run Native shell commands, we make the Java program dependent on the underlying operating system. For example, a Java program running specifically Linux shell commands cannot run as-is on a Windows machine mainly because Windows has a different folder structure and shell commands.
Examples:
The first three examples will look at implementing the ProcessBuilder class to run shell commands in Java. The following example is for the RunTime class.
Example 1: Loss of portability.
This example shows what happens if we execute a Java program meant for the Linux/Unix operating system on a Windows operating system.
Java
// if we execute a Java program meant for the Linux/Unix // operating system on a Windows operating system import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; public class ShellCommandRunner4 { public static void main(String[] args) { try { System.out.println( System.getProperty("os.name")); System.out.println(); // This process cannot be run on Windows. So the // program will throw an exception. ProcessBuilder pb = new ProcessBuilder("sh", "-c", "ls"); // Exception thrown here because folder // structure of Windows and Linux are different. pb.directory( new File(System.getProperty("user.home"))); // It will throw and exception Process process = pb.start(); StringBuilder output = new StringBuilder(); BufferedReader reader = new BufferedReader(new InputStreamReader( process.getInputStream())); String line; while ((line = reader.readLine()) != null) { output.append(line + "\n"); } int exitVal = process.waitFor(); if (exitVal == 0) { System.out.println( "**************************** The Output is ******************************"); System.out.println(output); System.exit(0); } } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } }
Example 2: Run a simple shell command
This example shows how to run a simple Windows shell command. We use a list to build commands and then execute them using the «start» method of the ProcessBuilder class. The program runs the command to find the chrome browser processes from the tasklist running in the machine.
Java
// Run a simple Windows shell command import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; public class ShellCommandRunner { public static void main(String[] args) { ProcessBuilder processBuilder = new ProcessBuilder(); List<String> builderList = new ArrayList<>(); // add the list of commands to a list builderList.add("cmd.exe"); builderList.add("/C"); builderList.add("tasklist | findstr chrome"); try { // Using the list , trigger the command processBuilder.command(builderList); Process process = processBuilder.start(); // To read the output list BufferedReader reader = new BufferedReader(new InputStreamReader( process.getInputStream())); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } int exitCode = process.waitFor(); System.out.println("\nExited with error code : " + exitCode); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } }
Example 3: Run a bat file
This example shows how to run a simple .bat program in the Java console. The .bat file displays the windows system information.
Java
// Run a simple .bat program in the Java console import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; public class ShellCommandRunner3 { public static void main(String[] args) { try { // File location for the bat script File dir = new File("D:\\bat_scripts"); // Command to run the bat file in the same // console ProcessBuilder pb = new ProcessBuilder( "cmd.exe", "/C", "sysinfo.bat"); pb.directory(dir); Process process = pb.start(); StringBuilder output = new StringBuilder(); BufferedReader reader = new BufferedReader(new InputStreamReader( process.getInputStream())); String line; while ((line = reader.readLine()) != null) { output.append(line + "\n"); } int exitVal = process.waitFor(); if (exitVal == 0) { System.out.println( "**************************** The Output is ******************************"); System.out.println(output); System.exit(0); } } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } }
Example 4:Run a shell command using the RunTime class.
This example shows how to run a simple command using the RunTime class. We use the exec() method of the Runtime class.
Java
// Run a simple command using the RunTime class import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; public class ShellCommandRunner2 { public static void main(String[] args) { try { Process process = Runtime.getRuntime().exec("where java"); StringBuilder output = new StringBuilder(); BufferedReader reader = new BufferedReader(new InputStreamReader( process.getInputStream())); String line; while ((line = reader.readLine()) != null) { output.append(line + "\n"); } int exitVal = process.waitFor(); if (exitVal == 0) { System.out.println( "**************************** The Output is ******************************"); System.out.println(output); System.exit(0); } } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } }
In this guide, we will show you how to run a command using Java in Linux or Windows machine. This will execute commands such as in command prompt in Windows or bash in Linux.
The Process API in Java lets you execute commands in the System. For example, printing the current directory, showing the network interfaces, and more. The ProcessBuilder accepts a command and arguments in an array. Here’s an example.
Executing a Command using ProcessBuilder
Below is a sample code on how to execute or run a command using Java. First, we create a new ProcessBuilder and add the command.
Next, we start the process using the start() method.
Then, we read the output by getting the InputStream from the process and putting it inside the BufferedReader.
Wait for the process to complete by invoking the waitFor() method.
Lastly, we close the resources and destroy the process.
public void runCommand(String... command) { ProcessBuilder processBuilder = new ProcessBuilder().command(command); try { Process process = processBuilder.start(); //read the output InputStreamReader inputStreamReader = new InputStreamReader(process.getInputStream()); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String output = null; while ((output = bufferedReader.readLine()) != null) { System.out.println(output); } //wait for the process to complete process.waitFor(); //close the resources bufferedReader.close(); process.destroy(); } catch (IOException | InterruptedException e) { e.printStackTrace(); } }
Testing in Windows Machine
Let’s try to test it in Windows by executing commands. Take note that the “cd”, “dir”, or “copy” commands are not executable by itself. They are part of cmd.exe command. Therefore, we need to call in first the cmd and pass the commands.
Other commands are executable by itself eg. “ipconfig”, “java”, etc.
public static void main(String... args) { Main main = new Main(); //test windows commands //in windows, cd, dir, copy, etc. are not executable commands //they are part of the windows command interpreter cmd.exe //therefore we need to call cmd.exe with option /C then our command to execute main.runCommand("cmd", "/C", "dir"); main.runCommand("ipconfig", "/all"); }
And this will show you the output of listing all the files and directories in your working directory and the network configuration with the ipconfig command.
Testing in Linux Machine
Now, let’s try to test it in Linux Machine. As mostly the commands in Linux are already available in bash, we don’t need to add “bash -c” in our commands. In any case that your command is not working, try adding “bash”, “-c” first in your command array argument.
public static void main(String... args) { Main main = new Main(); //test command in linux main.runCommand("pwd"); main.runCommand("ifconfig", "-a"); }
Here, we try to print the current working directory and the network configurations available. Here’s a sample output:
You can even run a shell script by just putting the script file location and starting with a forward slash eg., “/home/your-script.sh”.
That’s it for this guide. You have learned how to execute or run a command using Java in Windows or Linux systems. Let us know in the comments if this guide helps you. Also, you might want to visit our tutorial on how to convert images to base64 in Java.