Execute Command not work in Java - java

Execute Command worked well in Terminal, but not in Java code.
String cmd = "find -name javax.jar";
Process process = Runtime.getRuntime().exec(cmd);
BufferedReader reader = new BufferedReader(new InputStreamReader(
process.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null)
{
System.out.println("" + line);
}
System.out.println("Line : "+line);

When you spawn a process with
Runtime.getRuntime().exec(cmd);
the process is started from the same working directory as the Java process. If Java was run from a different working directory than you ran the find -name javax.jar in console, you will see different results.

i think you may try to add the path of find.
like find /var/tmp -name

Related

Exit(1) when running exec on java

I am running sed command in java program when i execute my java file in linux.
when i ran the command alone in linux, this will work -> sed '1d;$d' /home/sample/testdata.txt > /home/output/testupdate.txt
however when i ran my java program in linux, its returning exit(1) error . i have read through and use as an array but its still failing .
public static void main(String[] args) {
String[] cmd = {"sed", "sed '1d;$d' /home/sample/testdata.txt > /home/output/testupdate.txt"};
String s;
Process p;
try {
p = Runtime.getRuntime().exec(cmd);
BufferedReader br = new BufferedReader(
new InputStreamReader(p.getInputStream()));
while ((s = br.readLine()) != null) {
System.out.println("line: " + s);
}
p.waitFor();
System.out.println("exit: " + p.exitValue());
p.destroy();
} catch (Exception e) {
}
}
Java is not a shell so does not handle redirects - your original command only works via your Linux shell which understands ">".
You can make Java launch the shell to execute the command, say if you are using bash:
String[] cmd = {"/bin/bash", "-c"
, "sed '1d;$d' /home/sample/testdata.txt > /home/output/testupdate.txt"};
Alternatively see the other helpful comments which link to other pages on dealing with the redirects within the Java code, or to do it inside Java itself (such as with Files.lines / streams).
You don’t need sed. Java can do everything sed can do.
In your case, it appears you are using sed to remove the first and last line from a file. Here’s how you would do that in Java:
Path source = Path.of("/home/sample/testdata.txt");
Path destination = Path.of("/home/output/testupdate.txt");
long lineCount;
try (Stream<?> lines = Files.lines(source)) {
lineCount = lines.count();
}
long lastLine = lineCount - 1;
try (BufferedReader in = Files.newBufferedReader(source);
BufferedReader out = Files.newBufferedWriter(destination)) {
// Skip first line
String line = in.readLine();
long counter = 0;
while ((line = in.readLine()) != null) {
if (++counter < lastLine) {
out.write(line);
out.newLine();
}
}
}
If for some reason you absolutely need to use an external process, there are many other questions and answers which cover your mistake: > is not understood by sed. Normally, it is the shell (like bash) which interprets file redirection.
The proper way to run your command would have been:
ProcessBuilder builder =
new ProcessBuilder("sed", "1d;$d", "/home/sample/testdata.txt");
builder.redirectOutput(new File("/home/output/testupdate.txt"));
builder.redirectError(ProcessBuilder.Redirect.INHERIT);
Process p = builder.start();

getting error from java

How can I call a shell script through java code?
I have writtent the below code.
I am getting the process exit code as 127.
But it seems my shell script in unix machine is never called.
String scriptName = "/xyz/downloads/Report/Mail.sh";
String[] commands = {scriptName,emailid,subject,body};
Runtime rt = Runtime.getRuntime();
Process process = null;
try{
process = rt.exec(commands);
process.waitFor();
int x = process.exitValue();
System.out.println("exitCode "+x);
}catch(Exception e){
e.printStackTrace();
}
From this post here 127 Return code from $?
You get the error code if a command is not found within the PATH or the script has no +x mode.
You can have the code below to print out the exact output
BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
String s= null;
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
BufferedReader stdOut = new BufferedReader(new InputStreamReader(process. getErrorStream()));
String s= null;
while ((s = stdOut.readLine()) != null) {
System.out.println(s);
}
If you are getting an exit code, then your script is executed. There is a command that you are running inside of "Mail.sh", which is not succeccfully executed and returning a status code of 127.
There could be some paths that are explicitly set in your shell, but is not available to the script, when executed outside of the shell.
Try this...
Check if you are able to run /xyz/downloads/Report/Mail.sh in a shell terminal. Fix the errors if you have any.
If there are no errors when you run this in a terminal, then try running the command using a shell in your java program.
String[] commands = {"/bin/sh", "-c", scriptName,emailid,subject,body};
(Check #John Muiruri's answer to get the complete output of your command. You can see where exactly your script is failing, if you add those lines of code)

Running Bash from java does not work

I have this bash:
#!/bin/bash
# File to be tagged
inputfile="/dfs/sina/SinaGolestanirad-Project-OneTextEachTime/SinaGolestanirad-Project/Text.txt"
#inputfile="test/SampleInputs/longParagraph.txt"
# Tagged file to be created
#outputfile="test/SampleOutputs/NERTest.conll.tagged.txt"
outputfile="/dfs/sina/SinaGolestanirad-Project-OneTextEachTime/SinaGolestanirad-Project/1.Generate-Basic-Questions/Tagged-Named-Entites-Text.txt"
# Config file
#configfile="config/conll.config"
configfile="config/ontonotes.config"
# Classpath
cpath="target/classes:target/dependency/*"
CMD="java -classpath ${cpath} -Xmx8g edu.illinois.cs.cogcomp.LbjNer.LbjTagger.NerTagger -annotate ${inputfile} ${outputfile} ${configfile}"
echo "$0: running command '$CMD'..."
$CMD
When I run either java codes below they do not give any errors but they just show the bash file in my Eclipse Console, in other words they do not run the bash !! and the value for process.exitValue() is 1, by the way, my OS is CentOS, linux.
Firs JAVA code :
try {
Process process = new ProcessBuilder(command).start();
process.waitFor();
System.out.println(process.exitValue());
BufferedReader buf = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = "";
while ((line = buf.readLine()) != null) {
System.out.println("exec response: " + line);
}
} catch (Exception e) {
System.out.println(e);
}
Second JAVA code :
String command = "/dfs/sina/SinaGolestanirad-Project-OneTextEachTime/"
+ "SinaGolestanirad-Project/1.Generate-Basic-Questions/1.IllinoisNerExtended-DO-NOT-OPEN-BY-ECLIPSE/plaintextannotate-linux.sh";
StringBuffer output = new StringBuffer();
Process p;
try {
String[] cmd = new String[]{"/bin/bash",command};
p = Runtime.getRuntime().exec(cmd);
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(
p.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
System.out.println(output.toString());
} catch (Exception e) {
e.printStackTrace();
}
I also checked the bash file permission and it is executable as a program.
How can I run the bash file? The bash should run another program written in java.
-- LeBarton what is the exit code?
Check the output of p.exitValue()
p.waitFor()
InputStreamReader inputStreamReader = new InputStreamReader(p.getErrorStream());
While (inputStreamReader.ready()) { System.out.println(inputStreamReader.read(); }
This will show you the error output. Add this to the bottom below the try.. catch.
You will see the output that you would see on the command line. It will help you narrow down the error.
I found a link which may help, if your bash read some environmental variables.
$PATH variable isn't inherited through getRuntime().exec

How to execute terminal command in specific directory from java

I am trying to execute originate command in specific directory "/usr/local/freeswitch/bin", In bin I have to run executable file fs_cli by ./fs_cli command, In fs_cli I have to execute following command
originate loopback/1234/default &bridge(sofia/internal/1789)
Its working fine from terminal, The same command can be executed from bin
./fs_cli -x "originate loopback/1234/default &bridge(sofia/internal/1789)"
I tried folowing java program to do the above task
Process pr = Runtime.getRuntime().exec("./fs_cli -x \"originate loopback/1234/default &bridge(sofia/internal/1789#192.168.0.198)\"");
BufferedReader br = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String str = null;
while ((str = br.readLine()) != null) {
System.out.println(str);
}
I have creted symbolic link of fs_cli and placed in current location
The above program is showing following output
Output
-ERR "originate Command not found!
As far as I am concerned whwn above command is working fine with terminal it should be the same from java, So it shows I am wrong somewhere
Please help me to sort out this problem.
Use ProcessBuilder and supply a directory path
ProcessBuilder pb = new ProcessBuilder(
"./fs_cli",
"-x",
"originate loopback/1234/default &bridge(sofia/internal/1789#192.168.0.198)");
pb.directory(new File("..."));
Process pr = pb.start();
BufferedReader br = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String str = null;
while ((str = br.readLine()) != null) {
System.out.println(str);
}
Where possible, you should provide the command arguments as separate Strings, this will pass each as a separate argument to the process and take care of those arguments that need to be escaped by quotes for you (unless it's expecting the quotes, then you should include them anyway)
The other way is:
ProcessBuilder processBuilder = new ProcessBuilder( "/bin/bash", "-c", "cd /usr/local/freeswitch/bin && ./fs_cli -x \"originate loopback/1234/default &bridge(sofia/internal/1789)\"" );
processBuilder.start();

Java can't get full error when running an external command

I'm trying to compile typescript files in java.
Here is a ".ts" file which has errors:
alert("hello, typescript");
errrrrrrrrrrrrrrrrrrrrrrrrrror
When I compile in windows shell(cmd):
tsc hello.ts
It will report error with message:
E:/WORKSPACE/test/typescripts/hello.ts(2,0): The name 'errrrrrrrrrrrrrrrrrrrrrrrrror'
does not exist in the current scope
But when I do it in java:
String cmd = "cmd /C tsc hello.ts";
Process p = Runtime.getRuntime().exec(cmd);
String out = IOUtils.toString(p.getInputStream());
String error = IOUtils.toString(p.getErrorStream());
System.out.println("### out: " + out);
System.out.println("### err: " + error);
It prints:
### out:
### err: E:/WORKSPACE/test/typescripts/hello.ts(2,0):
You can see the detail errors is not captured. Where is wrong with my code?
update
I just made sure that the tsc.exe provided by MS has no such problem, and the one I run in this question is the tsc.cmd installed from npm npm install typescript
Have you tried using a raw Process/ProcessBuilder combination?
ProcessBuilder pb = new ProcessBuilder("cmd /C tsc hello.ts");
//merge error output with the standard output
pb.redirectErrorStream(true);
Process p = pb.start();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream(), Charset.forName("UTF-8")))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
I just spent a couple hours chasing the same problem.
In the end I worked around it by adding "2> errorfile.txt" to my command line. This redirects the stderr to a file and then I read and print that file.

Categories