Use Process.getInputStream() to get an InputStream that represents the stdout of the newly created process.

Note that starting/running external processes from Java can be very tricky and has quite a few pitfalls.

They are described in this excellent article, which also describes ways around them.

Answer from Joachim Sauer on Stack Overflow
🌐
Coderanch
coderanch.com › t › 751548 › java › Execute-Linux-Command-Return-Output
Execute Linux Command and Return Output (Java in General forum at Coderanch)
May 9, 2022 - Incidentally, in Linux, an SMB shared file path is in the form "//hostname/sharename/dirname/dirname/filename". Even outside of Java, since backslashes are perilous to Unix-style users. Yes, there is a Java library for working with CIFS file sharing. And no, I don't recommend using Runtime.exec() to execute a series of commands and especially not with redirects.
🌐
Baeldung
baeldung.com › home › java › core java › how to run a shell command in java
How to Run a Shell Command in Java | Baeldung
January 8, 2024 - For example, we can create a process builder for each isolated command and compose them into the pipeline: @Test public void givenProcessBuilder_whenStartingPipeline_thenSuccess() throws IOException, InterruptedException { List<ProcessBuilder> builders = Arrays.asList( new ProcessBuilder("find", "src", "-name", "*.java", "-type", "f"), new ProcessBuilder("wc", "-l")); List<Process> processes = ProcessBuilder.startPipeline(builders); Process last = processes.get(processes.size() - 1); List<String> output = readOutput(last.getInputStream()); assertThat("Results should not be empty", output, is(not(empty()))); }
Top answer
1 of 2
14

The primary reason why this doesn't work is that `$2` is not the same as `ls -1 | tail -1`, even when $2 is set to that string.

If your script accepts a literal string with a command to execute, you can use eval to do so.

I created a complete example. Please copy-paste it and verify that it works before you try applying any of it to your own code. Here's Test.java:

Copyimport java.io.*;

public class Test {
  public static void main(String[] args) throws Exception {
    String[] command = { "./myscript", "key", "ls -t | tail -n 1" };
    Process process = Runtime.getRuntime().exec(command);
    BufferedReader reader = new BufferedReader(new InputStreamReader(
        process.getInputStream()));
    String s;
    while ((s = reader.readLine()) != null) {
      System.out.println("Script output: " + s);
    }
  }
}

And myscript:

Copy#!/bin/bash
key="$1"
value=$(eval "$2")
echo "The command  $2  evaluated to: $value"

Here's how we can run myscript separately:

Copy$ ls -t | tail -n 1
Templates

$ ./myscript foo 'ls -t | tail -n 1'
The command  ls -t | tail -n 1  evaluated to: Templates

And here's the result of running the Java code:

Copy$ javac Test.java && java Test
Script output: The command  ls -t | tail -n 1  evaluated to: Templates 
2 of 2
0

As other posters pointed out already, the sub-process is not started in a shell, so the she-bang is not interpreted.

I got your example to work by explicitly starting the evaluation of the second parameter in a shell in jj.sh:

Copyvalue=`sh -c "$2"` 

Not nice, but works.

Other option may be to start the script in a shell explicitly, emulating the sh-bang:

CopyString[] cmd = { "/bin/sh", "jj.sh" , key,value};
🌐
Alvin Alexander
alvinalexander.com › java › java-exec-system-command-pipeline-pipe
Java exec: How to execute a system command pipeline in Java | alvinalexander.com
So, to use a feature like a Unix/Linux pipe (pipeline) -- which is a shell feature -- you have to invoke a shell, and then run your commands inside that shell. That's what I'm doing in the lines of code above, invoking a shell (/bin/sh), and then running the "ls -l /var/tmp | grep foo" command pipeline in that shell. I hope this tutorial on how to execute a system command pipeline (pipe) from Java has been helpful.
🌐
CodeJava
codejava.net › java-se › file-io › execute-operating-system-commands-using-runtime-exec-methods
How to Execute Operating System Commands in Java
July 27, 2019 - 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:
Find elsewhere
🌐
Crunchify
crunchify.com › macos tutorials › how to run windows, linux, macos terminal commands in java and return complete result
How to Run Windows, Linux, macOS terminal commands in Java and return complete Result • Crunchify
February 26, 2019 - 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.
🌐
Java2s
java2s.com › example › java › native-os › execute-shell-command-and-get-output.html
execute Shell Command And Get Output - Java Native OS
import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; public class Main{ public static void main(String[] argv) throws Exception{ String command = "java2s.com"; System.out.println(executeCommandAndGetOutput(command)); }//from www . j av a2s .c o m public static String executeCommandAndGetOutput(String command) throws Exception { Process proc = createAndExecuteProcess(command); logForProc(proc); return getOuputMessageOfCommand(proc.getInputStream()); } private static Process createAndExecuteProcess(String co
🌐
GitHub
gist.github.com › padcom › a5831bea701ef08ce944
Running a process and reading its output in Java · GitHub
Running a process and reading its output in Java · Raw · Execute.java · This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
🌐
Mkyong
mkyong.com › home › java › how to execute shell command from java
How to execute shell command from Java - Mkyong.com
January 3, 2019 - c:mysql then the prompt changes to: mysql> now in this we type sql commands. Can we achieve/automate this with java? ... The article would be even better with a note on how to run a shell file sitting in the resources directory. Thanks for the jump start anyway ! ... I really like your articles on Java. For this one i guess i could not do as mentioned. I googled and figured out that you need to first connect to the linux box from java and then you can execute shell commands.
🌐
ExtraVM
thishosting.rocks › how-to-execute-a-shell-command-using-java
How To Execute a Shell Command Using Java
May 19, 2021 - The exec() method is for executing commands directly or running .bat/.sh files. try { // -- Linux -- // Run a shell command // Process process = Runtime.getRuntime().exec("ls /home/mkyong/"); // Run a shell script // Process process = ...
🌐
Medium
beknazarsuranchiyev.medium.com › run-terminal-commands-from-java-da4be2b1dc09
Run terminal commands from Java. In this article, we will discuss how to… | by Beknazar | Medium
April 24, 2022 - It’s quite helpful to know how to run the operating system processes via Java code. The ProcessBuilder class is used to build Process object. We specify the commands and other configurations in the ProcessBuilder. We work on actual execution with Process instance. For example to get the status code from the process, to get its id, to see the output, to wait, and to kill the process.
🌐
Princeton CS
introcs.cs.princeton.edu › java › 15inout › linux-cmd.html
Java and the Linux Command Line
From the shell, type the java command below. [wayne] ~/introcs/hello> java HelloWorld Hello, World If all goes well, you should see the output of the program - Hello, World. If your program gets stuck in an infinite loop, type Ctrl-c to break out. If you are entering input from the keyboard, you can signify to your program that there is no more data by typing Ctrl-d for EOF (end of file). You should type this character on its own line. When I try to run java I get: Exception in thread "main" java.lang.NoClassDefFoundError.
🌐
GitHub
gist.github.com › 4283217
Executing a linux bash command from a java program and reading the response of it which spans multiple lines · GitHub
Executing a linux bash command from a java program and reading the response of it which spans multiple lines
Top answer
1 of 14
324

Here is the way to go:

Runtime rt = Runtime.getRuntime();
String[] commands = {"system.exe", "-get t"};
Process proc = rt.exec(commands);

BufferedReader stdInput = new BufferedReader(new 
     InputStreamReader(proc.getInputStream()));

BufferedReader stdError = new BufferedReader(new 
     InputStreamReader(proc.getErrorStream()));

// Read the output from the command
System.out.println("Here is the standard output of the command:\n");
String s = null;
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);
}

Read the Javadoc for more details here. ProcessBuilder would be a good choice to use.

2 of 14
88

A quicker way is this:

public static String execCmd(String cmd) throws java.io.IOException {
    java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\A");
    return s.hasNext() ? s.next() : "";
}

Which is basically a condensed version of this:

public static String execCmd(String cmd) throws java.io.IOException {
    Process proc = Runtime.getRuntime().exec(cmd);
    java.io.InputStream is = proc.getInputStream();
    java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
    String val = "";
    if (s.hasNext()) {
        val = s.next();
    }
    else {
        val = "";
    }
    return val;
}

I know this question is old but I am posting this answer because I think this may be quicker.

Edit (For Java 7 and above)

Need to close Streams and Scanners. Using AutoCloseable for neat code:

public static String execCmd(String cmd) {
    String result = null;
    try (InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream();
            Scanner s = new Scanner(inputStream).useDelimiter("\\A")) {
        result = s.hasNext() ? s.next() : null;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return result;
}
🌐
Coderanch
coderanch.com › t › 426616 › java › run-linux-command-java
run linux command in java (I/O and Streams forum at Coderanch)
To capture the output, you just want to run { "/sbin/ifconfig", "-a" }. A couple of things, though: If you have enough network interfaces, ifconfig will fill up its output buffer printing their details. Then your program will be waiting for it to exit, but it will be waiting for your program ...
🌐
GeeksforGeeks
geeksforgeeks.org › java › how-to-execute-native-shell-commands-from-java-program
How to Execute Native Shell Commands from Java Program? - GeeksforGeeks
March 3, 2021 - 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.