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.