Some Perl lines won't execute from Java Runtime.getRuntime().exec() - java

I have a strange behavior when calling a perl script from Java.
The perl code is:
#!/usr/bin/env perl
use warnings;
print "dada\n";
$file = "settings.txt";
open $ds, "<", $file;
print "doudou\n";
while ($line = <$ds>){
print "$line\n";
last if $. == 4;
}
print "dodo\n";
close $ds;
As you can see, in this code I want to read the file "settings.txt" which contents :
1 : a
2 : b
3 : c
4 : d
And this script works when called from cygwin and the output is :
dada
doudou
1 : a
2 : b
3 : c
4 : d
dodo
But when I call it from Java using the following code:
String line;
String cmd = "perl C:\\Data\\Tests\\match_settings.pl";
try {
Process proc = Runtime.getRuntime().exec(cmd);
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
while ((line = in.readLine()) != null) {
System.out.println("Line :" + line);
}
in.close();
} catch (IOException a) {
// TODO Auto-generated catch block
a.printStackTrace();
}
Then when the Java function is executed, I get the output:
Line :dada
Line :doudou
Line :dodo
Which means that $line = <$ds> is not well executed, but I don't know why.
Any idea ?
Sorry for the long post, wanted to be as precise as possible.
PS : I know some of you are wondering "Why not read the settings.txt file by Java code himself ?" but that's not the question here ;)

It seems that the folder from which your perl code is executed is not the same when executing from Cygwin and Java. So the perl Script can't find your file.
You should add error checking in your perl code, and verify your current working dir directory.
I would write:
#!/usr/bin/env perl
use warnings;
use Cwd;
my $cwd = cwd();
print "dada\n";
print "In folder: $cwd";
$file = "settings.txt";
open ($ds, "<", $file) || die "Can't open settings.txt. Error code: $!";
print "doudou\n";
while ($line = <$ds>){
print "$line\n";
last if $. == 4;
}
print "dodo\n";
close $ds;
This will help you debug why, when your script is executed from Java, you don't get the expected results.
You should also redirect stderr to stdout in your Java code, so you will get error lines.

Related

Java Runtime.getRuntime() does not print any output or exit code

While running
send = Runtime.getRuntime().exec(myscript)
the script runs as intended but when I try to read any sort of output or exit code, I run into some problems
for example, if my .sh script is just the following two lines
#!/bin/bash
exit 10
printing send.exitValue() returns me exit code 0. Which is not what i am expecting.
This is also in fact after waiting for the program to finish with by using waitFor().
I am also attempting to read the input/output/error streams but they are all null with no values, with the following snippets
val stdInput = BufferedReader(InputStreamReader(send.inputStream))
val stdError = BufferedReader(InputStreamReader(send.errorStream))
send.waitFor()
println("Here is the standard output of the command:\n")
var s: String? = null
while (stdInput.readLine().also { s = it } != null) {
println(s)
}
println("Here is the standard error of the command:\n")
val e: String? = null
while (stdError.readLine().also { s = it } != null) {
println(e)
}
The program I am writing is heavily dependent on the error codes to determine where the program failed if such a case happened. I cannot seem to find out how or why I get 0 as my exit code regardless

Terminal command won't print

I have a code which calls a specific command within the Mac Terminal, I then use a buffered reader to read and print the result from the terminal. I have been doing this with a couple of commands, only problem is I am now in need of using the command ps -ef | grep google (program name is of course different, but for now I'll just use google). The only issue by using this command is the fact that the buffered reader doesn't seem to be able to read and print the outcome. I am 100% sure that the actual command works, as I have tried to run the command in the terminal alone. I am not exactly sure why this problem is all of a sudden happening now.
The command is used to check whether a specific application is running and where it has been launched from.
The code I am using is the one below here.
try {
String procss;
Process pRun = Runtime.getRuntime().exec("ps -ef | grep google");
BufferedReader input = new BufferedReader(new InputStreamReader(pRun.getInputStream()));
while ((procss = input.readLine()) != null) {
if(!procss.contains("Contents"))
{
//Do something
}
}
input.close();
} catch (Exception err) {
err.printStackTrace();
}
To give an example of a command where it has worked without any problem, I have also just included a working code below. To show how I would actually like it to work, but just with the right command ps -ef | grep google instead.
try {
String procss;
Process pRun = Runtime.getRuntime().exec("top -F -R -o cpu");
BufferedReader input = new BufferedReader(new InputStreamReader(pRun.getInputStream()));
while ((procss = input.readLine()) != null) {
if(!procss.contains("testApplication"))
{
//Do something
}
}
input.close();
} catch (Exception err) {
err.printStackTrace();
}
I am not sure whether I need to use another method of reading the outcome or what I have to do for my code to actually work again.

Displaying DOS error message using Rhino/JavaScript/Java

I am trying to run a DIR command using a program similar to Rhino language (the program is using Java/JavaScript).
If there are any syntax error or any other error, I want to print out the error message using the function below:
function CatchDOSError()
{
var ErrorMSG = new java.io.BufferedReader(new java.io.InputStreamReader(java.lang.Runtime.getRuntime().exec("cmd /c dir \\C:\Test\Data /s /b /a-D > c:\Test\fileRunDIR.txt").getErrorStream()));
while (( ErrorMSG.readLine()) != null)
{
println(ErrorMSG);
}
ErrorMSG.close();
}
If I run this function, all what I get as an output in the console is: "java.io.BufferedReader#71fbs019".
If I run the DOS command from CMD manually, the error message is "The System cannot find the path". This is the error message which I want it to be displayed using the function above. Not sure if there are conversion issues or something wrong with my function.
Any help is appreciated, thank you.
When you do
while (( ErrorMSG.readLine()) != null) {
println(ErrorMSG);
}
You discard the line after checking it wasn't null and then print the Reader itself (which doesn't override toString() and isn't the line). I think you wanted,
var line = "";
while (( line = ErrorMSG.readLine()) != null) {
println(line);
}

Diff exiting with error code 1

I am trying to apply diff on two folders on the files which have same name.
I am checking name of files and then applying diff over them.
I am also calculating CKJM Metrics for them.
On running it is exiting with error code 1.
Kindly help in running CMD operations through java program .
Error : Exited with error code 1
Exited with error code 1
Exited with error code 1
Exited with error code 1
Exited with error code 1
Exited with error code 1
Exited with error code 1
Exited with error code 1
Exited with error code 1
Exited with error code 1
Exited with error code 1
Exited with error code 1
Exited with error code 1
Exited with error code 1
Exited with error code 1
Exited with error code 1
Exited with error code 1
Exited with error code 1
Exited with error code 1
Exited with error code 1
Exited with error code 1
Exited with error code 1
The common file names are [Inverse Trigono.doc, Limit _ Continuity & Differentia
bility.doc, Parabola.doc, Permutation and combination.doc, Probability.doc, Quad
ratic Equation and Expression.doc, Sequence and Series.doc, Solution of triangle
.doc, Straight Line.doc, TEST PAPER.rar, Vectors.doc]
p.s. I have gone through nearly all similar questions asked here but it seems like This is a bit different.
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ListFiles111 {
public static void main(String[] args) {
// Path of Folder 1
String path1 = "C:\\Users\\hi\\Downloads\\IIT Typing\\IIT Typing";
// Path of Folder 2
String path2 = "C:\\Users\\hi\\Downloads\\IIT Typing\\IIT Typing"; 2
File folder1 = new File(path1);
File folder2 = new File(path2);
ArrayList<String> commonfiles = new ArrayList<>();
// Array list of files of folder 1 created.
List<File> filesList1 = Arrays.asList(folder1.listFiles());
// Array list of files of folder 1 created
List<File> filesList2 = Arrays.asList(folder2.listFiles());
for (File f1 : filesList1)
{
if (f1.isFile())
{
for (File f2 : filesList2)
{
if (f2.isFile() && f1.getName().equals(f2.getName()))
{
// Adding common name files in new Array list
commonfiles.add(f1.getName());
try
{
Runtime rt = Runtime.getRuntime();
String[] cmd = new String[5];
cmd[0] = "cmd.exe " ;
cmd[1] = "/C " ;
cmd[2] = "diff ";
cmd[3] = f1.getName() + " ";
cmd[4] = f2.getName();
Process pr = rt.exec( cmd );
BufferedReader input = new BufferedReader(
new InputStreamReader(pr.getInputStream()));
String line = null;
while ((line = input.readLine()) != null)
{
System.out.println(line);
}
int exitVal = pr.waitFor();
System.out.println("Exited with error code "
+ exitVal);
}
catch (Exception e)
{
System.out.println(e.toString());
e.printStackTrace();
}
try
{
Runtime rt = Runtime.getRuntime();
String[] cmdd = new String[6];
cmdd[0] = "cmd.exe " ;
cmdd[1] = "/C " ;
cmdd[2] = "java ";
cmdd[3] = "-jar ";
cmdd[4] = "C:\\Users\\hi\\Desktop\\ckjm-1.9\\build\\ckjm-1.9.jar ";
cmdd[5] = "C:\\Users\\hi\\Desktop\\*.class";
Process pr = rt.exec( cmdd );
BufferedReader input = new BufferedReader(
new InputStreamReader(pr.getInputStream()));
String line = null;
while ((line = input.readLine()) != null)
{
System.out.println(line);
}
int exitVal = pr.waitFor();
System.out.println("Exited with error code "
+ exitVal);
}
catch (Exception e)
{
System.out.println(e.toString());
e.printStackTrace();
}
}
}
}
}
System.out.println("The common file names are " + commonfiles);
}
}
Consider using ProcessBuilder instead of Runtime.exec(), it allows you a lot more control than Runtime.exec(), and will allow you to read the stdout and stderr of the utility you are calling, which will help you find the cause of your problem.
Another thing is you pass your files to your utility using File.getName() which is only going to return the name of the file itself, not its complete path. Therefore, your diff utility will interpret those file names according to its working directory, which is probably different from the folder where your files are stored. To solve this, you can either use ProcessBuilder to set the working directory before invoking your utility, or you can use File.getAbsolutePath() or File.getCanonicalPath() to pass the full path.
I'm not sure if it is relevant on Windows, but have you tried removing the trailing spaces from the arguments you pass to Runtime.exec()? Remember that you are not actually building a command string. The arguments that you pass to Runtime.exec() will be passed "as-is" to your operating system, and will end up "as-is" in the created process. in your case, this means that your OS will be looking for a binary called "cmd.exe ", which I'm pretty sure doesn't exist. Same goes for all your other parameters.
Also, Don't call "cmd.exe", call your program directly. What's the point of calling the shell and telling it to open your program. Just open the program directly.
Answering this, even though it is old because I was just looking for something similar.
The return code '1' is from cmd.exe and indicates a "partial" issue according to this https://msdn.microsoft.com/en-us/library/ms194959(v=vs.100).aspx link. It may not be getting as far as running "diff" at all. Or perhaps, as suggested above, cmd.exe cannot find the files to pass as in/output to diff. Again, this would result in diff not actually being called and the return code coming from the shell; not the diff program.
Hth

Running Bash Script in Java

So essentially, I am trying to run the command "/dir/command -arg" to change the LED color on a USB device in Java. I am using Ubuntu 10.04. When I run the command from the terminal, it works just fine.
However, I tried every iteration of Runtime.exec() that I could find and none of them seem to work. I then created a script with the following contents:
#!/bin/bash
echo "hello"
/dir/command -arg
when I run this from a terminal it works just fine. However when I run
#Override
public void run() {
String[] lookupCmd = {"/bin/sh","-c", "sh /dir/script.sh"};
try {
Runtime runtime = Runtime.getRuntime();
Process lookupProc = runtime.exec(lookupCmd);
lookupProc.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(lookupProc.getInputStream()));
String line = reader.readLine();
while (line != null) {
id.add(line);
System.out.println(line);
line = reader.readLine();
}
} catch (Exception e) {
System.err.println(e);
}
}
"hello" print but nothing else. There is no error.
My other command should not yield any output, but simply change the color of an LED. However when I run it with the same command but a different arg which yields an ouput, it still only prints "hello".
I also made sure that my user has permissions to the /dev folder with the usb device.
I wasn't running the error stream, so I've added that.
After that I realized I was missing an environment variable, so added:
String[] envar = {"VAR=path"}
and called:
runtime.exec(lookupCmd, envar);
Works great now.

Categories

Resources