Java executing linux command

How to execute system commands (linux/bsd) using Java

I am attempting to be cheap and execute a local system command ( uname -a ) in Java. I am looking to grab the output from uname and store it in a String. What is the best way of doing this? Current code:

public class lame < public static void main(String args[]) < try < Process p = Runtime.getRuntime().exec("uname -a"); p.waitFor(); BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); String line=reader.readLine(); while (line != null) < System.out.println(line); line = reader.readLine(); >> catch(IOException e1) <> catch(InterruptedException e2) <> System.out.println("finished."); > > 

5 Answers 5

Your way isn’t far off from what I’d probably do:

Runtime r = Runtime.getRuntime(); Process p = r.exec("uname -a"); p.waitFor(); BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream())); String line = ""; while ((line = b.readLine()) != null) < System.out.println(line); >b.close(); 

Handle whichever exceptions you care to, of course.

Can combine this with org.apache.commons.io.IOUtils.toString(p.getInputStream(), «UTF-8») from Apache Commons for small outputs (as one String)

That is the best way to do it. Also you can use the ProcessBuilder which has a variable argument constructor, so you could save a line or two of code

It’s not the best way since the command is executed using shell and, in result, it’s susceptible to OS command injection if the command arguments are taken from user input. ProcessBuilder is definitely safer in this aspect.

«I am attempting to be cheap and execute a local system command (uname -a). » — it is the BEST way to be cheap and execute a local system command. What you refer to is the best way to be UNsusceptible to OS command injection 😉

You know, it’s a bit like asking a programmer for the fastest way down the cliff. 🙂 I have found OS command injections in a Java apps using a StackOverflow-inspired execution pattern, so I think anything that mentions Runtime.exec() deserves a big, fat warning here.

You know, it’s a lot like that, I agree, still. can’t really change people’s behavior if they just copy-paste from SO instead of re-evaluate their original idea, big fat warnings included 🙁

What you are doing looks fine. If your command is only returning a single string, you don’t need the while loop, just store the reader.readLine() value in a single String variable.

Also, you probably should do something with those exceptions, rather than just swallowing them.

I know this is very old but still.

Reading the article here: http://www.javaworld.com/article/2071275/core-java/when-runtime-exec—won-t.html
It is my understanding that you should first read the output and error streams of your executed command and only then waitFor the return value of your process.

I know this questionis very old, but I just wanted to add some information that might come handy to some people.

If you just want to run uname command from java code, better use the System class to get information about the system.

Читайте также:  Linux removing directory with contents

It will not only remove the dependency of running the terminal command, but it will also work independently of the Operating System.

System Class can give you the following information

Keys : Values

—> os.version : OS Version
—> os.name : OS Name

—> os.arch : OS Architecture

—> java.compiler : Name of the compiler you are using

—> java.ext.dirs : Extension directory path

—> java.library.path : Paths to search libraries whenever loading

—> user.dir : Current working directory of User

—> user.name : Account name of User

—> java.vm.version : JVM implementation version

—> java.vm.name : JVM implementation name

—> java.home : Java installation directory

—> java.runtime.version : JVM version

ex : If I am running a Linux based system, Say Ubuntu, the following command will give me the information about it.

Источник

How to Run a Shell Command in Java

We rely on other people’s code in our own work. Every day.

It might be the language you’re writing in, the framework you’re building on, or some esoteric piece of software that does one thing so well you never found the need to implement it yourself.

The problem is, of course, when things fall apart in production — debugging the implementation of a 3rd party library you have no intimate knowledge of is, to say the least, tricky.

Lightrun is a new kind of debugger.

It’s one geared specifically towards real-life production environments. Using Lightrun, you can drill down into running applications, including 3rd party dependencies, with real-time logs, snapshots, and metrics.

Learn more in this quick, 5-minute Lightrun tutorial:

announcement - icon

Building or modernizing a Java enterprise web app has always been a long process, historically. Not even remotely quick.

That’s the main goal of Jmix is to make the process quick without losing flexibility — with the open-source RAD platform enabling fast development of business applications.

Critically, it has very minimal impact on your server’s performance, with most of the profiling work done separately — so it needs no server changes, agents or separate services.

Simply put, a single Java or Kotlin developer can now quickly implement an entire modular feature, from DB schema, data model, fine-grained access control, business logic, BPM, all the way to the UI.

Jmix supports both developer experiences – visual tools and coding, and a host of super useful plugins as well:

announcement - icon

Slow MySQL query performance is all too common. Of course it is. A good way to go is, naturally, a dedicated profiler that actually understands the ins and outs of MySQL.

The Jet Profiler was built for MySQL only, so it can do things like real-time query performance, focus on most used tables or most frequent queries, quickly identify performance issues and basically help you optimize your queries.

Critically, it has very minimal impact on your server’s performance, with most of the profiling work done separately — so it needs no server changes, agents or separate services.

Читайте также:  Linux как скопировать диск

Basically, you install the desktop application, connect to your MySQL server, hit the record button, and you’ll have results within minutes:

announcement - icon

DbSchema is a super-flexible database designer, which can take you from designing the DB with your team all the way to safely deploying the schema.

The way it does all of that is by using a design model, a database-independent image of the schema, which can be shared in a team using GIT and compared or deployed on to any database.

And, of course, it can be heavily visual, allowing you to interact with the database using diagrams, visually compose queries, explore the data, generate random data, import data or build HTML5 database reports.

announcement - icon

The Kubernetes ecosystem is huge and quite complex, so it’s easy to forget about costs when trying out all of the exciting tools.

To avoid overspending on your Kubernetes cluster, definitely have a look at the free K8s cost monitoring tool from the automation platform CAST AI. You can view your costs in real time, allocate them, calculate burn rates for projects, spot anomalies or spikes, and get insightful reports you can share with your team.

Connect your cluster and start monitoring your K8s costs right away:

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

> CHECK OUT THE COURSE

1. Overview

In this article, we’ll learn how to execute a shell command from Java applications.

First, we’ll use the .exec() method the Runtime class provides. Then, we’ll learn about ProcessBuilder, which is more customizable.

2. Operating System Dependency

Shell commands are OS-dependent as their behavior differs across systems. So, before we create any Process to run our shell command in, we need to be aware of the operating system on which our JVM is running.

Additionally, on Windows, the shell is commonly referred to as cmd.exe. Instead, on Linux and macOS, shell commands are run using /bin/sh. For compatibility on these different machines, we can programmatically append cmd.exe if on a Windows machine or /bin/sh otherwise. For instance, we can check if the machine where the code is running is a Windows machine by reading the “os.name” property from the System class:

boolean isWindows = System.getProperty("os.name") .toLowerCase().startsWith("windows");

3. Input and Output

Often, we need to connect the input and output streams of the process. In detail, the InputStream acts as the standard input, and the OutputStream acts as the standard output of the process. We must always consume the output stream. Otherwise, our process won’t return and will hang forever.

Let’s implement a commonly used class called StreamGobbler, which consumes an InputStream:

private static class StreamGobbler implements Runnable < private InputStream inputStream; private Consumerconsumer; public StreamGobbler(InputStream inputStream, Consumer consumer) < this.inputStream = inputStream; this.consumer = consumer; >@Override public void run() < new BufferedReader(new InputStreamReader(inputStream)).lines() .forEach(consumer); >>

This class implements the Runnable interface, which means any Executor could execute it.

4. Runtime.exec()

Next, we’ll spawn a new process using the .exec() method and use the StreamGobler created previously.

Читайте также:  Linux установить run файл

For example, we can list all the directories inside the user’s home directory and then print it to the console:

Process process; if (isWindows) < process = Runtime.getRuntime() .exec(String.format("cmd.exe /c dir %s", homeDirectory)); >else < process = Runtime.getRuntime() .exec(String.format("/bin/sh -c ls %s", homeDirectory)); >StreamGobbler streamGobbler = new StreamGobbler(process.getInputStream(), System.out::println); Future future = executorService.submit(streamGobbler); int exitCode = process.waitFor(); assertDoesNotThrow(() -> future.get(10, TimeUnit.SECONDS)); assertEquals(0, exitCode);

Here, we created a new sub-process with .newSingleThreadExecutor() and then used .submit() to run our Process containing the shell commands. Additionally, .submit() returns a Future object we utilize to check the result of the process. Also, make sure to call the .get() method on the returned object to wait for the computation to complete.

NOTE: JDK 18 deprecates .exec(String command) from the Runtime class.

4.1. Handle Pipes

Currently, there is no way to handle pipes with .exec(). Fortunately, the pipes are a shell feature. So, we can create the whole command where we want to use pipe and pass it to .exec():

Here, we list all the directories in the user’s home and search for the “Desktop” folder.

5. ProcessBuilder

Alternatively, we can use a ProcessBuilder, which is preferred over the Runtime approach because we can customize it instead of just running a string command.

In short, with this approach, we’re able to:

  • change the working directory our shell command is running in using .directory()
  • change environment variables by providing a key-value map to .environment()
  • redirect input and output streams in a custom way
  • inherit both of them to the streams of the current JVM process using .inheritIO()

Similarly, we can run the same shell command as in the previous example:

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); Future future = executorService.submit(streamGobbler); int exitCode = process.waitFor(); assertDoesNotThrow(() -> future.get(10, TimeUnit.SECONDS)); assertEquals(0, exitCode); 

6. Conclusion

As we’ve seen in this quick tutorial, we can execute a shell command in Java in two distinct ways.

Generally, if we’re planning to customize the execution of the spawned process, for example, to change its working directory, we should consider using a ProcessBuilder.

As always, the sources are available over on GitHub.

announcement - icon

Slow MySQL query performance is all too common. Of course it is. A good way to go is, naturally, a dedicated profiler that actually understands the ins and outs of MySQL.

The Jet Profiler was built for MySQL only, so it can do things like real-time query performance, focus on most used tables or most frequent queries, quickly identify performance issues and basically help you optimize your queries.

Critically, it has very minimal impact on your server’s performance, with most of the profiling work done separately — so it needs no server changes, agents or separate services.

Basically, you install the desktop application, connect to your MySQL server, hit the record button, and you’ll have results within minutes:

Источник

Оцените статью
Adblock
detector