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 OverflowUse 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.
To collect the output you could do something like
Process p = Runtime.getRuntime().exec("my terminal command");
p.waitFor();
BufferedReader buf = new BufferedReader(new InputStreamReader(
p.getInputStream()));
String line = "";
String output = "";
while ((line = buf.readLine()) != null) {
output += line + "\n";
}
System.out.println(output);
This would run your script and then collect the output from the script into a variable. The link in Joachim Sauer's answer has additional examples of doing this.
Videos
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
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};