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
Related
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.
file = D:\Unix\tr.exe "Æ" "~" < "C:\SourceFiles\source.csv" > "D:\tgt"
When i execute this command using the below code in java
Process process = Runtime.getRuntime().exec(file);
am getting the following error
D:\Unix\tr.exe: too many arguments
PS : File contains Æ characters am trying to replace all those characters with ~
Any suggestions please ?
You're passing unicode in the CMD, I guess that causes the problem.
Set chcp xxx on the CMD and try.
refer below link for chcp codes
https://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/chcp.mspx?mfr=true
You have to program the io redirection yourself. This is usually the bash that takes care of it.
The result of the exec() call is a process. This process can then be used to get the STDIN of the process. Send the data to that process using that stream.
The way you call it, you send another command line option to tr, which is the < and > redirectors and the filenames.
Process process = System.getRuntime().exec(strBatchFileName);
OutputStream stdin = process.getOutputStream();
sendFileToStream(out);
InputStream stdout = process.getInputStream();
loadResultFromStream(stdout);
This is a pseudocode example, where sendFileToStream(...) feeds the input file into the TR process, and the loadResultFromStream(...) will load the result.
You may need to utilize threads to feed and read if the data is larger than the stream's buffer.
The question is kind of a duplicate and you will find a ProcessBuilder example here: Runtime's exec() method is not redirecting the output
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 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 am trying to run following command in my Java program
Runtime.getRuntime().exec("ls -lrt service/logs/post/level2.log | awk '{print $9}'");
or
Runtime.getRuntime().exec("ls -lrt service/logs/post/level2* | awk '{print $9}'");
it gives me following error
ls: 0653-341 The file | does not exist.
ls: 0653-341 The file awk does not exist.
ls: 0653-341 The file '{print does not exist.
ls: 0653-341 The file $9}' does not exist.
Kindly help me
Pipes are a shell-based construct, not actual runnable commands. There are two options to do this as I see it:
Do the piping yourself within Java. Invoke the ls command first, get a handle to its OutputStream and then invoke awk connecting the first Process's output to the second Process' input stream.
Invoke the bash shell directly from Java, passing in the entire command as an argument to bash's -c parameter. That way all the piping is done within the single process.
As for the token-based errors, you should be invoking these commands with an array of strings; each element represents a token of the command line. So try, for example:
Runtime.getRuntime().exec(new String[] { "ls", "-lrt", "service/logs/post/level2.log" });
in order to invoke the ls command. I don't think this is strictly necessary in this case, but it will be for the awk command, since Java doesn't know anything about shell-specific quoting rules, so by default tokenises a single-string input on the space character. That's why your awk script was being split in two.
Edit (in response to comments): In the first option, I meant simply that you're able to pipe the output between the two processes yourself, in Java.
Imagine if you've created a process as so:
Process ls = Runtime.getRuntime().exec("ls -lrt service/logs/post/level2.log");
Now, this process will run and generate some output (which we know is going to be a line describing that file). We can get the stream for this output like so:
InputStream lsOut = ls.getInputStream();
Now, we want to run that awk process:
Process awk = Runtime.getRuntime().exec(new String[] { "awk", "{print $9}"});
The awk process of course will sit there are the moment waiting for input, since it knows it's going to be reading from stdin. So, we grab the input stream that it's going to be using:
OutputStream awkIn = awk.getOutputStream();
Now, the piping bit - we read the output of the ls command and pass it into the input for awk:
// TODO add buffering, error handling, probably run this in a separate thread
int datum = lsOut.read();
while (datum != -1)
{
awkIn.write(datum);
datum = lsOut.read();
}
This reads the output of ls (byte-by-byte for simplicity, using byte array buffers would be much faster but I'm trying to illustrate the concept simply) and writes it to the input of awk.
Then it's just a matter of reading the output from the awk process and dealing with it as you see fit.