- How to invoke a Linux shell command from Java
- 3 Answers 3
- How to Run a Shell Command in Java
- Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:
- > CHECK OUT THE COURSE
- 1. Overview
- 2. Operating System Dependency
- 3. Input and Output
- 4. Runtime.exec()
- 4.1. Handle Pipes
- 5. ProcessBuilder
- 6. Conclusion
- How do i run a Linux terminal cmd from a java program [duplicate]
- 6 Answers 6
How to invoke a Linux shell command from Java
I am trying to execute some Linux commands from Java using redirection (>&) and pipes (|). How can Java invoke csh or bash commands? I tried to use this:
Process p = Runtime.getRuntime().exec("shell command");
i can understand the question for other commands, but for cat: why the hell don’t you just read in the file?
Everyone gets this wrong first time — Java’s exec() does not use the underlying system’s shell to execute the command (as kts points out). The redirection and piping are features of a real shell and are not available from Java’s exec().
System.exit(0) is not inside conditional checking if process is done, so it will always exit without outputting errors. Never write conditionals without braces, to avoid exactly this sort of mistake.
3 Answers 3
exec does not execute a command in your shell
Process p = Runtime.getRuntime().exec(new String[]);
EDIT:: I don’t have csh on my system so I used bash instead. The following worked for me
Process p = Runtime.getRuntime().exec(new String[]);
@Narek. Sorry about that. I fixed it by removing the extra \» ‘s Apparently they aren’t needed. I don’t have csh on my system, but it works with bash.
Warning: this solution will very likely run into the typical problem of it hanging because you didn’t read its output and error streams. For example: stackoverflow.com/questions/8595748/java-runtime-exec
Use ProcessBuilder to separate commands and arguments instead of spaces. This should work regardless of shell used:
import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; public class Test < public static void main(final String[] args) throws IOException, InterruptedException < //Build command Listcommands = new ArrayList(); commands.add("/bin/cat"); //Add arguments commands.add("/home/narek/pk.txt"); System.out.println(commands); //Run macro on target ProcessBuilder pb = new ProcessBuilder(commands); pb.directory(new File("/home/narek")); pb.redirectErrorStream(true); Process process = pb.start(); //Read output StringBuilder out = new StringBuilder(); BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream())); String line = null, previous = null; while ((line = br.readLine()) != null) if (!line.equals(previous)) < previous = line; out.append(line).append('\n'); System.out.println(line); >//Check result if (process.waitFor() == 0) < System.out.println("Success!"); System.exit(0); >//Abnormal termination: Log command parameters and output and throw ExecutionException System.err.println(commands); System.err.println(out.toString()); System.exit(1); > >
@Stephan I’ve updated the example code above to remove the logging statements and variables that were declared outside the pasted code, and it should now compile & run. Feel free to try and let me know how it works out.
Building on @Tim’s example to make a self-contained method:
import java.io.BufferedReader; import java.io.File; import java.io.InputStreamReader; import java.util.ArrayList; public class Shell < /** Returns null if it failed for some reason. */ public static ArrayListcommand(final String cmdline, final String directory) < try < Process process = new ProcessBuilder(new String[] ) .redirectErrorStream(true) .directory(new File(directory)) .start(); ArrayList output = new ArrayList(); BufferedReader br = new BufferedReader( new InputStreamReader(process.getInputStream())); String line = null; while ( (line = br.readLine()) != null ) output.add(line); //There should really be a timeout here. if (0 != process.waitFor()) return null; return output; > catch (Exception e) < //Warning: doing this is no good in high quality applications. //Instead, present appropriate error messages to the user. //But it's perfectly fine for prototyping. return null; >> public static void main(String[] args) < test("which bash"); test("find . -type f -printf '%T@\\\\t%p\\\\n' " + "| sort -n | cut -f 2- | " + "sed -e 's/ /\\\\\\\\ /g' | xargs ls -halt"); >static void test(String cmdline) < ArrayListoutput = command(cmdline, "."); if (null == output) System.out.println("\n\n\t\tCOMMAND FAILED: " + cmdline); else for (String line : output) System.out.println(line); > >
By the way, if somebody can tell me why I need four and eight backslashes there, instead of two and four, I can learn something. There is one more level of unescaping happening than what I am counting.
Edit: Just tried this same code on Linux, and there it turns out that I need half as many backslashes in the test command! (That is: the expected number of two and four.) Now it’s no longer just weird, it’s a portability problem.
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:
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:
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:
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.
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.
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.
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:
How do i run a Linux terminal cmd from a java program [duplicate]
I am trying to call my rrdtool cmd from a java class, not sure how to go about it. I have tested my RRDTool cmd from my terminal and it is successful, see below.
rrdtool update mydb.rrd 1385056701:6:5
6 Answers 6
You can use the below command format to run your Linux command.
Runtime r = Runtime.getRuntime(); Process p = r.exec(yourcmd);
Hope you get your answers here.
public class ShellTest < public static void main(String[] args) throws java.io.IOException, java.lang.InterruptedException < // Get runtime java.lang.Runtime rt = java.lang.Runtime.getRuntime(); // Start a new process: UNIX command ls java.lang.Process p = rt.exec("ls"); // Show exit code of process System.out.println("Process exited with code http://blog.art-of-coding.eu/executing-operating-system-commands-from-java/" rel="nofollow">also check here for more details