Using `Runtime.getRuntime().exec()` to get the output from `top` - java

I'd like run the top -n 1 command using Runtime.getRuntime().exec(String) method and get the output of top -n 1 into my Java program.
I've tried the standard way of getting a processes output with a BufferedReader and using the returned Processes InputStream but that returned no data.
I also tried the following...
String path = "/home/user/Desktop/";
String cmd = "#!/bin/sh\ntop -n 1 > " + path + "output";
File shellCmd = new File(path + "topscript.sh");
PrintWriter writer = new PrintWriter(shellCmd);
writer.write(cmd);
writer.flush();
Runtime.getRuntime().exec("chmod +x " + shellCmd.getAbsolutePath());
Runtime.getRuntime().exec(shellCmd.getAbsolutePath());
Which creates the shell script and the output but the output is empty. However, if I then load up my local shell and run the script that the code above made, I get the correct output in the output file.
What's going wrong?

String cmd = "#!/bin/sh\ntop -n1 -b > " + path + "output";
File shellCmd = new File(path + "topscript.sh");
PrintWriter writer = new PrintWriter(shellCmd);
writer.write(cmd);
writer.flush();
Runtime.getRuntime().exec("chmod +x " + shellCmd.getAbsolutePath());
ProcessBuilder pb = new ProcessBuilder(shellCmd.getAbsolutePath());
Map<String, String> enviornments = pb.environment();
enviornments.put("TERM", "xterm-256color");
Process process = pb.start();
BufferedReader inputStreamReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader errorStreamReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String str = inputStreamReader.readLine();
System.out.println(str);
System.out.println(errorStreamReader.readLine());
Use ProcessBuilder with setting TERM variables.
and if want to redirect top to file. need to add -b option to avoid error: initializing curses.

Related

Issues while Invoking Python process using java process builder

I am using java process builder to start python process with one flag and with one argument as shown below. But i don't see any exception nor process starts up.
Command i want to run is
python oc_db5.py -c input.json
location of file oc_db5.py is
/opt/jvision/grpc/gui
My code is shown below
processBuilder = new ProcessBuilder(
Arrays.asList(
"python",
"oc_db5.py",
"-c",
"input.json"));
processBuilder.directory(new File("/opt/jvision/grpc/gui"));
processBuilder.start();
logger.info("Process started ..." + new Date());
int count = 0;
BufferedReader br = new BufferedReader(new InputStreamReader(
process.getInputStream()));
while ((lineData = br.readLine()) != null) {
System.out.println("line: " + ++count + " " + lineData);
logger.info("line: " + ++count + " " + lineData);
}
process.waitFor();
process.getErrorStream();
process.waitFor();
process.exitValue();
I can see that log file contains entry "process start..." but i don't really see that process is started. Wondering what i am missing.
Can you check if python is in your PATH? I have similar problem with custom command long long time ago. You can use absolute path to try it :).
You can also check you enviromental variables via
Map env = System.getenv();
If you are using Linux you can start process like "sleep 1000" then check it is present in system process table via "ps aux | grep sleep" or something like it :)

Calling imagemagick from java not working, direct call works

I am having the following java code to blur faces in images - the variable convert is set to /usr/bin/mogrify
//String []cmd = {convert, "-region", f.w+"x"+f.h+"+"+x+"+"+y, "-blur 0.0x10.0", path};
String cmd = convert + " -region " + f.w+"x"+f.h+"+"+x+"+"+y + " -blur 0.0x10.0 " + "\"" + path + "\"";
System.out.println(cmd);
// System.out.println(strJoin(cmd, " "));
Process p = Runtime.getRuntime().exec(cmd);
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
p.waitFor();
But nothing happens on the images.
The program also outputs the command line it would call, for example:
/usr/bin/mogrify -region 37x44+1759+881 -blur 0.0x10.0 "/home/self/.wine/drive_c/windows/profiles/self/My Pictures/test/pic00164.jpg"
If I call this line manually, everything works fine.
As you can see from the comments, I also tried supplying cmd as an array which should automatically escape the spaces in my path - same effect: none.
Never build command line by hands - there is no single portable solution for this. It works only in rare cases, where no spaces or (double) quotes are present in the command line.
Use process builder instead:
ProcessBuilder pb = new ProcessBuilder(
convert, "-region", f.w+"x"+f.h+"+"+x+"+"+y, "-blur 0.0x10.0", path);
pb.redirectError();
Process process = pb.start();
BufferedReader in = new BufferedReader(
new InputStreamReader(process.getInputStream()));
getErrorStream() - as mentioned in a comment - was the key to success. The escaping did not work the way I tried it. Then I tried it with an array and found our that I have to split up the blur option.
This works:
String []cmd = {convert, "-region", f.w+"x"+f.h+"+"+x+"+"+y, "-blur", "0.0x10.0", path};

how to execute batch command (imagemagick) with java

I used the terminal command to convert all the images in the folder into RGB images using imagemagick tool
"C:\Documents and Settings\admin\My
Documents\NetBeansProjects\Archiveindexer\resources\T0003SathyabamaT\Active\CBE_2014_03_02_FE_04_MN_IMAGES_CONVERTED"
is my image folder
terminal command:
myimagefolder> mogrify -colorspace RGB *.jpg
This works fine. But when run this using java it is not working
File destpathfinalconv = new File("C:/Documents and Settings/admin/My Documents/NetBeansProjects/Archiveindexer/T0003SathyabamaT/Active/CBE_2014_03_02_FE_04_MN_IMAGES_CONVERTED");
ProcessBuilder pb = new ProcessBuilder("mogrify", "-colorspace RGB", destpathfinalconv.toString(),
"*.jpg");
pb.redirectErrorStream(true);
Process p = pb.start();
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = br.readLine()) != null) {
System.err.println(line);
}
System.err.println("Error "+p.waitFor());
System is throwing error "mogrify.exe: unrecognized option
`-colorspace RGB' # error/mogrify.c/MogrifyImageCommand/4254. Error 1"
Any idea please suggest.
You are specifying '-colorspace RGB' as a single argument, but it should be two arguments. And you should combine the path and file and search pattern into a single argument. The constructor of ProcesBuilder should be called like this:
ProcessBuilder pb = new ProcessBuilder("mogrify", "-colorspace", "RGB",
destpathfinalconv.toString() + "\\" + "*.jpg");
Try this:
ProcessBuilder pb = new ProcessBuilder(
"mogrify",
"-colorspace",
"RGB",
destpathfinalconv.toString(),
"*.jpg");
Explanation: Each String argument in the ProcessBuilder ends up as a "word" (according to shell parlance) or a separate parameter in the resulting execve call.
Combining "-colorspace RGB" results in a single parameter to mogrify, which is the (unknown) option "-colorspace\ RGB".

Java ProcessBuilder and bash

I am trying to execute a bash script from Java with ProcessBuilder
my code is :
Process createUser = buildProcess(
"/bin/su",
"-c",
"\"/opt/somedir/testdir/current/bin/psql",
"--command",
commandForUserCreation,
/* "'select * from users'", */
"--dbname",
"mydbname\"",
"myuser"
);
The problem is that I receive error:
/bin/su: unrecognized option '--dbname'
If I put echo in first place of my commands it prints correct command in bash and if I copy/paste this command it works!
Please, help me to resolve this issue.
You need to supply the whole command to execute by su as a single argument. Try this:
Process createUser = buildProcess(
"/bin/su",
"-c",
"/opt/vmware/vpostgres/current/bin/psql --command " + commandForUserCreation + " --dbname mydbname",
myuser
);
This is what I use in processBuilder:
String[] command = new String[] {"echo", "Hello"};
String workspace = "/bin/su";
System.out.println("Trying to run command: "+ Arrays.toString(command));
ProcessBuilder probuilder = new ProcessBuilder(command);
probuilder.directory(new File(workspace));
Process process = probuilder.start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
System.out.printf("Output of running %s is:\n",Arrays.toString(command));
while ((line = br.readLine()) != null) {
System.out.println(line);
}
I hope it helps.

java Processbuilder - exec a file which is not in path on OS X

Okay i'm trying to make ChucK available in exported Processing sketches, i.e. if i export an app from Processing, the ChucK VM binary will be executed from inside the app. So as a user of said app you don't need to worry about ChucK being in your path at all.
Right now i'm generating and executing a bash script file, but this way i don't get any console output from ChucK back into Processing:
#!/bin/bash
cd "[to where the Chuck executable is located]"
./chuck --kill
killall chuck # just to make sure
./chuck chuckScript1.ck cuckScriptn.ck
then
Process p = Runtime.getRuntime().exec("chmod 777 "+scriptPath);
p = Runtime.getRuntime().exec(scriptPath);
This works but i want to run ChucK directly from Processing instead, but can't get it to execute:
String chuckPath = "[folder in which the chuck executable is located]"
ProcessBuilder builder = new ProcessBuilder
(chuckPath+"/chuck", "test.ck");
final Process process = builder.start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while((line = br.readLine()) != null) println(line);
println("done chuckin'! exitValue: " + process.exitValue());
Sorry if this is newbie style :D
ProcessBuilder builder = new ProcessBuilder
(chuckPath+"/chuck", chuckPath+"/test.ck");
the args all need an absolute path.

Categories