I am now on a linux machine. I have a Java program which would run some linux command, for example ps, top, list or free -m.
The way to run a command in Java is as follows:
Process p = Runtime.getRuntime().exec("free -m");
How could I collect the output by Java program? I need to process the data in the output.
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.
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.
As for some command need to wait for a while, add p.waitFor(); if necessary.
public static void main(String[] args) {
CommandLineHelper obj = new CommandLineHelper();
String domainName = "google.com";
//in mac oxs
String command = "ping -c 3 " + domainName;
String output = obj.executeCommand(command);
System.out.println(output);
}
private String executeCommand(String command) {
StringBuffer output = new StringBuffer();
Process p;
try {
p = Runtime.getRuntime().exec(command);
p.waitFor();
BufferedReader reader =
new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
} catch (Exception e) {
e.printStackTrace();
}
return output.toString();
}
The technicalities of calling an external process are quite involved. The jproc library helps abstracting over these by automatically consuming the output of the command and providing the result as a string. The example above would be written like this:
String result = ProcBuilder.run("free", "-m");
It also allows to set a timeout, so that your application isn't blocked by an external command that is not terminating.
public String RunLinuxGrepCommand(String command) {
String line = null;
String strstatus = "";
try {
String[] cmd = { "/bin/sh", "-c", command };
Process p = Runtime.getRuntime().exec(cmd);
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = in.readLine()) != null) {
strstatus = line;
}
in.close();
} catch (Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
pw.flush();
String stackTrace = sw.toString();
int lenoferrorstr = stackTrace.length();
if (lenoferrorstr > 500) {
strstatus = "Error:" + stackTrace.substring(0, 500);
} else {
strstatus = "Error:" + stackTrace.substring(0, lenoferrorstr - 1);
}
}
return strstatus;
}
This functioin will give result of any linux command
Related
I'm performing the following code to execute linux commands in my android application that I'm creating:
public void RunAsRoot(String[] cmds){
Process p = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(p.getOutputStream());
for (String tmpCmd : cmds) {
os.writeBytes(tmpCmd+"\n");
}
os.writeBytes("exit\n");
os.flush();
}
I want to know if there is a way to know what the command is returning after it is executing. for example, if I do "ls" I would like to see what the command wold normally output.
try this code :
try {
Process process = Runtime.getRuntime().exec("ls");
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
StringBuilder result=new StringBuilder();
String line = "";
while ((line = bufferedReader.readLine()) != null) {
result.append(line);
}
TextView tv = (TextView)findViewById(R.id.textView1);
tv.setText(result.toString());
}
catch (IOException e) {}
Let's go by a "String function" example
String shell_exec(String s)
{
String line="",output="";
try
{
Process p=Runtime.getRuntime().exec(new String[]{"sh","-c",s});
BufferedReader b=new BufferedReader(new InputStreamReader(p.getInputStream()));
while((line=b.readLine())!=null){output+=line+"\r\n";}
}catch(Exception e){return "error";}
return output;
}
Now just use it:
String s=shell_exec("ls /data/data/com.mycompany.myapp");
I'm trying to write a function that has the name of a service as parameter. The problem is that i can only start and stop a service in cmd ( in windows) only if i run it as administrator. How can i run cmd in java as administrator? Can you please help me?? Thanks
public String stop(String name) {
try {
List<String> command = new ArrayList<String>();
command.add("cmd.exe");
command.add("/c");
command.add("runas");
command.add("/user:Administrator");
command.add("\"net");
command.add("stop");
command.add(name + "\"");
System.out.println(command);
Process servicesProcess = new ProcessBuilder(command).start();
InputStream input = servicesProcess.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String line;
StringBuffer queryResult = new StringBuffer();
while ((line = reader.readLine()) != null) {
queryResult.append(line);
}
reader.close();
servicesProcess.destroy();
System.out.println(queryResult.toString());
if (queryResult.toString().toLowerCase().contains("failed") || queryResult.toString().toLowerCase().contains("error")) {
return "Failed #stop";
}
System.out.println("Stop service completed succesfully!");
return "Succes #stop";
} catch (IOException e) {
return "Failed #stop";
}
}
I also tried with this and still doesn't work
List<String> command = new ArrayList<String>();
command.add("cmd.exe");
command.add("/c");
command.add("Powrprof.dll");
command.add(",");
command.add("SetSuspendState");
command.add("net");
command.add("stop");
command.add(name);
System.out.println(command);
Process servicesProcess = new ProcessBuilder(command).start();
package online_test;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class cmdline_test {
/**
* #param args
*/
public static void main(String[] args) {
try {
String[] command = new String[3];
command[0] = "cmd";
command[1] = "/c";
command[2] = "c: && dir && cd snap";
Process p = Runtime.getRuntime().exec(command);
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = reader.readLine();
while (line != null) {
System.out.println(line);
line = reader.readLine();
}
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String Error;
while ((Error = stdError.readLine()) != null) {
System.out.println(Error);
}
while ((Error = stdInput.readLine()) != null) {
System.out.println(Error);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
When I run this code, I get the output of this code printed to the console. However, I wasn't able to figure out how to copy that output to a file. How would I go about doing so?
Use a ProcessBuilder:
final File outputFile = Paths.get("somefile.txt").toFile();
final ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "whatever")
.redirectOutput(outputFile)
.redirectErrorStream(true);
final Process p = pb.start();
// etc
Read the javadoc carefully; there is a lot more you can do with it (affecting the environment, changing the working directory etc).
Also, do you really need to go through an interpreter at all?
A more simple solution is to change the outputstream of System.out to a file. This way, every time you invoke System.out.println(...) it will write to said file. Add this to the start of your program:
File file =
new File("somefile.log");
PrintStream printStream = null;
try {
printStream = new PrintStream(new FileOutputStream(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
System.setOut(printStream);
You can do the same for System.err for printing errors to a different file.
The below code is not getting executed completely after this line " bufferedReader.readLine(); ". The Program works fine when i execute the system command with
out mentioning IPAddress of the remote PC.
class Test
{
public static void main(String arg[])
{
Process p;
Runtime runTime;
String process = null;
try {
runTime = Runtime.getRuntime();
p = runTime.exec("sc \\xx.xx.xx.xx query gpsvc"); // For Windows
InputStream inputStream = p.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String line = bufferedReader.readLine();
process = "&";
while (line != null) {
line = bufferedReader.readLine();
process += line + "&";
}
StringTokenizer st = new StringTokenizer(proc, "&");
System.out.println("token size "+st.countTokens());
while (st.hasMoreTokens()) {
String testData = st.nextToken();
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
}
} catch (IOException e) {
System.out.println("Exception arise during the read Processes");
e.printStackTrace();
}
}
}
Check your command inside exec method
p = runTime.exec("sc \\xx.xx.xx.xx query gpsvc");
The syntax is wrong here and if you execute this from command prompt, you will be prompted with the below question.
Would you like to see help for the QUERY and QUERYEX commands? [ y | n ]:
And the program wouldn't return until you enter y or n. Since the program is not terminating, you wouldn't be able to read the console output and that's the reason your program is getting stuck on String line = bufferedReader.readLine();
I trying to run multiple command shells from Java. I am able to do that (and get the output in the console using PrintWriter). However, I want to be able to get the output of each command in a separate String. Is that possible?
Here is a part of the code :
File wd = new File("/bin");
Process proc = null;
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);
out.println("cd ..");
out.println("ls");
System.out.println("moving to /var directory");
out.println("cd /var/");
out.println("ls");
//get output of ls command in string variable
out.println("cd ..");
out.println("cd /etc/");
out.println("ls -a");
out.println("ps");
out.println("exit");
try {
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
proc.waitFor();
in.close();
out.close();
proc.destroy();
}
catch (Exception e) {
e.printStackTrace();
}
Have you tried putting a section like
StringBuilder builder = new StringBuilder();
String line = null;
while ((line = in.readLine()) != null) {
builder.append(line).append("\n");
}
String commandOutput = builder.toString();
after each command? Is that roughly what you are trying to achieve?