I have some Java code that calls a Python script:
String[] cmd = new String[]{"python", "path/to/script", "arg1", "arg2"}
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(cmd);
As long as the Python script contains no errors it works fine, but as soon as it does it breaks. However, I don't get the error message that I would get if I would run the Python script directly from the command line, so I have to search myself what went wrong where. Not very efficient.
Is it possible to get this message by adding some lines to my Java code?
See When Runtime.exec() won't for many good tips on creating and handling a process correctly. Then ignore it refers to exec and use a ProcessBuilder to create the process. Also break a String arg into String[] args to account for things like paths containing space characters.
Now to the specifics of the problem at hand, it sounds like it is the output from the error stream that is missing. As you noted, calling proc.getErrorStream() and processing that output should fit the requirement.
Related
i am trying to execute awk command in java for linux/unix os but the thing is when i execute the command it does not show any error it.But after execution there is no output and it takes fraction of second to execute i dont know the problem please help .
the code is
process p =new process():
yes = "awk '{print $1}' /root/Desktop/net/net.zone >> /root/Desktop/net/net.txt";
p = Runtime.getRuntime().exec(yes);
Thank you for your help
Starting command line processes correctly with Java isn't easy. I suggest you use commons-exec instead of trying it yourself.
Now you have two things in the command line which need special handing:
Single quotes around the AWK script. When you pass each argument as a individual strings to CommandLine via addArgument, you don't need the quotes anymore.
The output redirection.
Since you create a child process, you are in control of stdin and stout. That means you need to open the target file for append in Java, wrap it in a PumpStreamHandler and pass that to DefaultExecutor. See this question for details: Process output from apache-commons exec
I need to run executable progam (.exe) in java. This program have two different operating modes: GUI and Command line. The syntax to launch the program from the command line is as follows :
C:\Users\Ermanno\Desktop\ "programFolder"\"program.exe" /stext output.txt
in this way the program store the outoput in the file "output.txt".
I tired it:
Process p = new ProcessBuilder("C:\\Users\\Ermanno\\Desktop\\programFolder\\program.exe" ,"/stext a.txt").start();
does not create the output file.
I also tired to use a file batch that contains the command and run it to java but the result is the same.
You need to pass each argument in a single string:
... program.exe", "/stext", "a.txt")...
Also make sure that you start a background thread which reads the output of the child process. If there is a problem, then the child will print an error message to it's standard output and if you don't actively read it, then this output will be lost.
For this, loop over the streams p.getInputStream() and p.getErrorStream().
The latter is especially important since you say "I also tired to use a file batch". Java doesn't do anything different than a batch script. If you can't run the command from batch, it won't work from Java, either.
My experience was horrible with using the JDK ProcessBuilder and Runtime.getRuntime().exec. I then moved to Apache commons-exec. Here is an example:
String line = "AcroRd32.exe /p /h " + file.getAbsolutePath();
CommandLine cmdLine = CommandLine.parse(line);
DefaultExecutor executor = new DefaultExecutor();
int exitValue = executor.execute(cmdLine);
I solved using file bath. This file contains the command.
String [] _s = {"cmd.exe", "/c", "start", "file.bat"};
Process pr = Runtime.getRuntime().exec(_s);
I have sample java code like below.
String testEfdDirectoryPath="D:\\test";
String efdExecutable = "test.cmd";
File executableFile = new File(testEfdDirectoryPath, efdExecutable);
ProcessBuilder pb=new ProcessBuilder();
$$pb.command("cmd.exe","/C",executableFile.toString());$$
pb.directory(new File(testEfdDirectoryPath));
Process p=pb.start();
int code=p.waitFor();
System.out.print(code);
In test.cmd there is actually a call to another java application. Unless I change the $$ marked line to the following to redirect its output, the another java app cannot be launched.
pb.command("cmd.exe","/C",executableFile.toString(),">output.txt");
Do you guys have any ideas? Thanks in advance. :)
Does your child process produce a lot of output (more than a few kilobytes)? If that is the case, you need to read that output from the process. You should try:
start the process
close the stdin of the process, so pb.getOutputStream().close()
repeatedly read from pb.getInputStream() and the error stream
This may be possible in one thread, or in multiple threads. Anyway, you should just take the explanation above as a list of keywords and try to search for an example code snippet that you can trust, preferrably from an Open Source application that does such a thing successfully.
Maybe http://commons.apache.org/exec/ can help you.
Windows cannot execute scripts directly; when you double click on a .cmd file it actually opens the file in cmd.exe. So try cmd.exe E:\\test\\test.cmd.
I am looking for a help regarding a shell script to redirect the output of a command to a file. I have a C program that reads the input from a serial port and display. I want this data to be redirected to a file. I am executing this from a java program by calling
Runtime r = Runtime.getRuntime();
Process procObj = r.exec("sh " + scriptfile);
I have tried writing the script file as
./program >> file.txt
The file.txt is not getting updated. Here, the program doesn't end until the connection to the port is lost, in a sense it is infinitely running. So my program keeps looking for data on the port and display as and when it is there.
I just need to redirect the same output to a file that I would use as a log.
I looked at How to make shell output redirect (>) write while script is still running? but not helpful.
Kindly help..
How much output does program generate? Using standard IO redirection will add a 4KB buffer between stdout and file. This means your program must output more than 4KB of data before the OS starts to write to the file.
To fix this, add stdout.flush() to your program when a "work unit" is complete (maybe a line but might be more than one line).
Can you try ./program >> file.txt 2>>file.txt, or ./program 2>&1 >>file.txt?
just try this
List<String> cmd = new ArrayList<String>();
cmd.add("sh");
cmd.add("-c");
cmd.add("program 1> file.txt 2>&1");
ProcessBuilder pb = new ProcessBuilder(cmd);
Process p = pb.start();
If you use standard C calls for output (printf, puts etc.), your output may get buffered. On C89 and onwards, it depends on the buffering mode (unbuffered, fully buffered, line buffered) and on the size of the buffer, whether your output is buffered at all and when the buffer is flushed (see http://www.gnu.org/software/libc/manual/html_node/Buffering-Concepts.html and man setvbuf).
By default, output to a file is fully buffered on Linux. If you want the output to appear immediately in the output file, you may:
use fflush() after each output operation
use the system call write() (man 2 write)
switch off buffering: setvbuf(stdout, NULL, _IONBF, 0); (https://stackoverflow.com/a/7876756/601203)
This behaviour is not related on the fact the you start your C program in a Java program via a shell script. This behaviour depends on the standard C library that you have linked into your program.
I have (in java),
rt.exec("qq.exe -i ..(some other parameters) > qq.log");//*1
when I run qq.exe -i ..(some other parameters) > qq.log in terminal It works fine and keeps the qq.log file correctly.
However using rt.exec (*1) doesnt work. " > qq.log" part causes problem. When I delete that part rt.exec (*1) works but I cant have qq.log file this time.
What causes this problem and Is there any soln??
rt.exec() can't execute sh/bat code. It's just invoking another program. When you try to redirect the output stream of qq.exe with the > symbol, which is specific to shell, java doesn't understand what to do.
An alternative is when you execute some program with the exec method, get the Process returned by rt.exec().
A Process can give you an OutputStream to the application, an InputStream from the application and even an ErrorStream for a started application.
With the InputStream, you can programmatically read the result of qq.exe and all you have to do is to write this into a file.
Java 7 added ProcesBuilder.Redirect class that allows to redirect input/output/error streams to/from files. It can be used like this:
ProcessBuilder builder = new ProcessBuilder("cat", "/proc/meminfo");
// Append all errors from process to log file:
builder.redirectError(Redirect.appendTo(new File("/tmp/my.log")));
Process process = builder.start();
Using corresponding methods you can redirect input and output. The full example is here: Run external process in Java 7.