Java program not displaying output from console - java

I've looked at several examples that are supposed to do this, and I don't see any difference between mine and others as far as core mechanics. Here is my code:
public class Console
{
public static void main(String[] args) throws IOException, InterruptedException{
Runtime rt = Runtime.getRuntime();
Process ps;
System.out.println("Gathering available network data...");
String cmd[] = {"ifconfig","|","grep","'inet addr:'"};
ps = rt.exec(cmd);
getOutput(cmd,ps);
}
public static String getOutput(String[] c, Process p) throws IOException, InterruptedException
{
Process ps = p;
String output="";
BufferedReader readerStd = new BufferedReader(new InputStreamReader(ps.getInputStream()));
BufferedReader readerErr = new BufferedReader(new InputStreamReader(ps.getInputStream()));
String line = null;
System.out.println("Result:");
while ((line = readerStd.readLine()) != null) {
System.out.println(line);
output+=line+"\n";
}
if((line = readerErr.readLine()) != null)
{
System.out.println("------ Std Err -------");
System.out.println(line);
while ((line = readerErr.readLine()) != null)
{
System.out.println(line);
}
}
return output;
}
}
The expected output is:
Gathering available network data...
Result:
inet addr:10.40.2.234 Bcast:10.40.2.255 Mask:255.255.255.0
inet addr:127.0.0.1 Mask:255.0.0.0
The actual output is:
Gathering available network data...
Result:
What am I doing wrong?

The pipe operator | is interpreted the shell so does not form part of the command itself. In addition the command needs to appear in a single token to prevent the grep segment being evaluated separately:
String cmd[] = { "bash", "-c", "ifconfig |grep 'inet addr:'" };

Related

how to extract specific lines from msinfo32 file using java code

i am writing a code to extract system info details i.e ram, processor speed and put them on a text file.
public void getSpecs(){
//run a cmd command to convert msinfo32 to .txt file
String[] command = {
"cmd",
};
Process p;
try{
p= Runtime.getRuntime().exec(command);
new Thread(new Sec(p.getErrorStream(), System.err)).start();
new Thread(new Sec(p.getInputStream(), System.out)).start();
PrintWriter pw= new PrintWriter(p.getOutputStream());
pw.println("msinfo32 /report .\\specs.txt");
pw.close();
p.waitFor();
}catch(Exception e){
e.printStackTrace();
}
}
}
This process is taking long and its converting the whole file.
msinfo32 exports the computer info into a file. It is expected to take some time as it retrieves a huge export for each computer/windows component.
I have done something similar using powershell
public static void main(String[] args) throws IOException {
//Set the commands
String cmd = "powershell.exe get-WmiObject ";
String[] win32CmdA = {"win32_processor", "win32_computerSystem", "win32_logicaldisk"};
for (String win32Cmd : win32CmdA) {
String info = runCmd(cmd + win32Cmd,
"MaxClockSpeed",
"TotalPhysicalMemory",
"DeviceID",
"FreeSpace");//Add as many atributes you want to return from powershell output
System.out.println(info); // You can use a file writer here
}
// //You can handle ErrorStream here
// String line;
// BufferedReader stderr = new BufferedReader(new InputStreamReader(
// powerShellProcess.getErrorStream()));
// while ((line = stderr.readLine()) != null) {
// System.out.println(line);
// }
}
private static String runCmd(String cmd, String... attrs) throws IOException {
Process powerShellProcess = Runtime.getRuntime().exec(cmd);
powerShellProcess.getOutputStream().close();
String line;
String result="";
BufferedReader stdout = new BufferedReader(new InputStreamReader(powerShellProcess.getInputStream()));
while ((line = stdout.readLine()) != null) {
if (line != null && line.contains(":")) {
String nameValue[] = line.split(":");
if (Arrays.asList(attrs).contains(nameValue[0].trim())) {
result+=nameValue[0] + " - " + nameValue[1] + "\n";
}
}
}
stdout.close();
return result;
}
The above code invokes the Windows Management Instrumentation (WMI) classes in powershell for specific components (processor, computerSystem and logicaldisk).
Then you define which values should be taken from the powershell output, like MaxClockSpeed, TotalPhysicalMemory, etc.
If you change the System.out.println(info); with a file writer you will have this info in a file.
Sample output (took ~3 seconds to run)
DeviceID - CPU0
MaxClockSpeed - 3401
TotalPhysicalMemory - 17053949952
DeviceID - C
FreeSpace - 56341774336
DeviceID - D
FreeSpace -
DeviceID - F
FreeSpace - 373687742464

Java runtime getInputStream ignores majority of terminal command output

I'm writing a Java program to capture the output of a terminal command. Under "normal" conditions, i.e. where I execute the command directly into the terminal myself, I can see the following result:
However, the output rendered by my Java program only captures a small subset of that, see here:
This is the codebase I'm speaking of:
import java.io.*;
class evmTest {
public static void main(String[] args) {
String evmResult = "";
String evmCommand = "evm --debug --code 7f00000000000000000000000000000000000000000000000000000000000000027f00000000000000000000000000000000000000000000000000000000000000027f00000000000000000000000000000000000000000000000000000000000000020101 run";
try {
Runtime r = Runtime.getRuntime();
Process p = r.exec(evmCommand);
BufferedReader in = new BufferedReader(new
InputStreamReader(p.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
evmResult += inputLine;
}
in.close();
} catch (IOException e) {
System.out.println(e);
}
}
}
Thus far I've not been able to determine why that code is only able to emit the paltry 0x. I've posted this question in the hopes that someone might be able to help me track down the cause of this error.
do it like this:
import java.io.*;
class evmTest {
public static void main(String[] args) {
String evmResult = "";
String evmCommand = "evm --debug --code 7f00000000000000000000000000000000000000000000000000000000000000027f00000000000000000000000000000000000000000000000000000000000000027f00000000000000000000000000000000000000000000000000000000000000020101 run";
try {
Runtime rt = Runtime.getRuntime();
String command = "evm --debug --code 7f00000000000000000000000000000000000000000000000000000000000000027f00000000000000000000000000000000000000000000000000000000000000027f00000000000000000000000000000000000000000000000000000000000000020101 run";
Process proc = rt.exec(command);
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);
}
} catch (IOException e) {
System.out.println(e);
}
}
}

Get the windows running process description In java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) {
try {
String line;
Process p = Runtime.getRuntime().exec
(System.getenv("windir") +"\\system32\\"+"tasklist.exe");
BufferedReader input = new BufferedReader(new InputStreamReader(
p.getInputStream()));
while ((line = input.readLine()) != null) {
System.out.println(line); // <-- Parse data here.
}
input.close();
} catch (Exception err) {
err.printStackTrace();
}
}
}
The output of this program shows the process list from windows task manager .....but i also need the Description of the running process ??? How do i get that???
tasklist.exe takes an optional parameter /v for verbose. This outputs the description
Example
taskmgr.exe 5648 Console 1 18,280 K Running 0:00:00 Windows Task Manager
You'll need to update your call to exec() to pass the "/v". Full example including parsing.
public static void main(String[] args) throws IOException {
String taskListExe = System.getenv("windir") + "\\system32\\" + "tasklist.exe";
Process p = Runtime.getRuntime().exec(new String[] { taskListExe, "/v" });
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
Pattern pattern = Pattern.compile("(.*?)\\s+(\\d+).*(\\d+:\\d+:\\d+)\\s+(.*?)");
String line;
while ((line = input.readLine()) != null) {
Matcher matcher = pattern.matcher(line);
if (matcher.matches()) {
System.out.println(String.format("%s, pid = %s, description = %s", matcher.group(1), matcher.group(2),
matcher.group(4)));
}
}
input.close();
}
Output
firefox.exe, pid = 3152, description = cmd - Get the windows running process description In java - Stack Overfl
taskmgr.exe, pid = 5648, description = Windows Task Manager
System Idle Process, pid = 0, description = N/A

How to Execute Windows Commands Using Java - Change Network Settings

In Java, I want to be able to execute a Windows command.
The command in question is netsh. This will enable me to set/reset my IP address.
Note that I do not want to execute a batch file.
Instead of using a batch file, I want to execute such commands directly. Is this possible?
Here is my implemented Solution for Future Reference:
public class JavaRunCommand {
private static final String CMD =
"netsh int ip set address name = \"Local Area Connection\" source = static addr = 192.168.222.3 mask = 255.255.255.0";
public static void main(String args[]) {
try {
// Run "netsh" Windows command
Process process = Runtime.getRuntime().exec(CMD);
// Get input streams
BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()));
// Read command standard output
String s;
System.out.println("Standard output: ");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// Read command errors
System.out.println("Standard error: ");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
}
Runtime.getRuntime().exec("netsh");
See Runtime Javadoc.
EDIT: A later answer by leet suggests that this process is now deprecated. However, as per the comment by DJViking, this appears not to be the case: Java 8 documentation. The method is not deprecated.
Use ProcessBuilder
ProcessBuilder pb=new ProcessBuilder(command);
pb.redirectErrorStream(true);
Process process=pb.start();
BufferedReader inStreamReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
while(inStreamReader.readLine() != null){
//do something with commandline output.
}
You can run the command with Runtime.getRuntime().exec("<command>") (eg. Runtime.getRuntime().exec("tree")). But, this will only run executables found in path, not commands like echo, del, ... But only stuff like tree.com, netstat.com, ... To run regular commands, you will have to put cmd /c before the command (eg Runtime.getRuntime().exec("cmd /c echo echo"))
public static void main(String[] args) {
String command="netstat";
try {
Process process = Runtime.getRuntime().exec(command);
System.out.println("the output stream is "+process.getOutputStream());
BufferedReader reader=new BufferedReader( new InputStreamReader(process.getInputStream()));
String s;
while ((s = reader.readLine()) != null){
System.out.println("The inout stream is " + s);
}
} catch (IOException e) {
e.printStackTrace();
}
}
This works.
Runtime#exec().

Java Runtime.getRuntime(): getting output from executing a command line program

I'm using the runtime to run command prompt commands from my Java program. However, I'm not aware of how I can get the output the command returns.
Here is my code:
Runtime rt = Runtime.getRuntime();
String[] commands = {"system.exe", "-send" , argument};
Process proc = rt.exec(commands);
I tried doing System.out.println(proc); but that did not return anything. The execution of that command should return two numbers separated by a semicolon. How could I get this in a variable to print out?
Here is the code I'm using now:
String[] commands = {"system.exe", "-get t"};
Process proc = rt.exec(commands);
InputStream stdIn = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(stdIn);
BufferedReader br = new BufferedReader(isr);
String line = null;
System.out.println("<OUTPUT>");
while ((line = br.readLine()) != null)
System.out.println(line);
System.out.println("</OUTPUT>");
int exitVal = proc.waitFor();
System.out.println("Process exitValue: " + exitVal);
But I'm not getting anything as my output, but when I run that command myself it works fine.
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.
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;
}
If use are already have Apache commons-io available on the classpath, you may use:
Process p = new ProcessBuilder("cat", "/etc/something").start();
String stderr = IOUtils.toString(p.getErrorStream(), Charset.defaultCharset());
String stdout = IOUtils.toString(p.getInputStream(), Charset.defaultCharset());
At the time of this writing, all other answers that include code may result in deadlocks.
Processes have a limited buffer for stdout and stderr output. If you don't listen to them concurrently, one of them will fill up while you are trying reading the other. For example, you could be waiting to read from stdout while the process is waiting to write to stderr. You cannot read from the stdout buffer because it is empty and the process cannot write to the stderr buffer because it is full. You are each waiting on each other forever.
Here is a possible way to read the output of a process without a risk of deadlocks:
public final class Processes
{
private static final String NEWLINE = System.getProperty("line.separator");
/**
* #param command the command to run
* #return the output of the command
* #throws IOException if an I/O error occurs
*/
public static String run(String... command) throws IOException
{
ProcessBuilder pb = new ProcessBuilder(command).redirectErrorStream(true);
Process process = pb.start();
StringBuilder result = new StringBuilder(80);
try (BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream())))
{
while (true)
{
String line = in.readLine();
if (line == null)
break;
result.append(line).append(NEWLINE);
}
}
return result.toString();
}
/**
* Prevent construction.
*/
private Processes()
{
}
}
The key is to use ProcessBuilder.redirectErrorStream(true) which will redirect stderr into the stdout stream. This allows you to read a single stream without having to alternate between stdout and stderr. If you want to implement this manually, you will have to consume the streams in two different threads to make sure you never block.
Also we can use streams for obtain command output:
public static void main(String[] args) throws IOException {
Runtime runtime = Runtime.getRuntime();
String[] commands = {"free", "-h"};
Process process = runtime.exec(commands);
BufferedReader lineReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
lineReader.lines().forEach(System.out::println);
BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
errorReader.lines().forEach(System.out::println);
}
#Senthil and #Arend answer (https://stackoverflow.com/a/5711150/2268559) mentioned ProcessBuilder. Here is the example using ProcessBuilder with specifying environment variables and working folder for the command:
ProcessBuilder pb = new ProcessBuilder("ls", "-a", "-l");
Map<String, String> env = pb.environment();
// If you want clean environment, call env.clear() first
//env.clear();
env.put("VAR1", "myValue");
env.remove("OTHERVAR");
env.put("VAR2", env.get("VAR1") + "suffix");
File workingFolder = new File("/home/user");
pb.directory(workingFolder);
Process proc = pb.start();
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);
Create class :
public class Utils {
public static final String SHEL_EXECUTE_ERROR = "SHEL_EXECUTE_ERROR";
public static String shellExec(String cmdCommand) {
final StringBuilder stringBuilder = new StringBuilder();
try {
final Process process = Runtime.getRuntime().exec(cmdCommand);
final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
}
} catch (Exception e) {
return SHEL_EXECUTE_ERROR;
}
return stringBuilder.toString();
}
}
and use:
final String shellExec = shellExec("cmd /c ver");
final String versionOS = shellExec.equals(SHEL_EXECUTE_ERROR) ? "empty" : shellExec;
If you write on Kotlin, you can use:
val firstProcess = ProcessBuilder("echo","hello world").start()
val firstError = firstProcess.errorStream.readBytes().decodeToString()
val firstResult = firstProcess.inputStream.readBytes().decodeToString()
Adapted from the previous answer:
public static String execCmdSync(String cmd, CmdExecResult callback) throws java.io.IOException, InterruptedException {
RLog.i(TAG, "Running command:", cmd);
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(cmd);
//String[] commands = {"system.exe", "-get t"};
BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
StringBuffer stdOut = new StringBuffer();
StringBuffer errOut = new StringBuffer();
// 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);
stdOut.append(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);
errOut.append(s);
}
if (callback == null) {
return stdInput.toString();
}
int exitVal = proc.waitFor();
callback.onComplete(exitVal == 0, exitVal, errOut.toString(), stdOut.toString(), cmd);
return stdInput.toString();
}
public interface CmdExecResult{
void onComplete(boolean success, int exitVal, String error, String output, String originalCmd);
}
Pretty much the same as other snippets on this page but just organizing things up over an function, here we go...
String str=shell_exec("ls -l");
The Class function:
public String shell_exec(String cmd)
{
String o=null;
try
{
Process p=Runtime.getRuntime().exec(cmd);
BufferedReader b=new BufferedReader(new InputStreamReader(p.getInputStream()));
String r;
while((r=b.readLine())!=null)o+=r;
}catch(Exception e){o="error";}
return o;
}
Process p = Runtime.getRuntime().exec("ping google.com");
p.getInputStream().transferTo(System.out);
p.getErrorStream().transferTo(System.out);
Try reading the InputStream of the runtime:
Runtime rt = Runtime.getRuntime();
String[] commands = {"system.exe", "-send", argument};
Process proc = rt.exec(commands);
BufferedReader br = new BufferedReader(
new InputStreamReader(proc.getInputStream()));
String line;
while ((line = br.readLine()) != null)
System.out.println(line);
You might also need to read the error stream (proc.getErrorStream()) if the process is printing error output. You can redirect the error stream to the input stream if you use ProcessBuilder.

Categories

Resources