3

I want to execute a command like this in java code,

gzip -c /tmp/specificPreffix_2013-11-06.txt > /tmp/specificPreffix_2013-11-06.txt.gz

My system is RHEL5, and I have granted the file access permission.

It doesn't work when I use the open source org.apache.commons.exec.DefaultExecutor. Could anyone help to point out why this happened, or let me know if there is another way. Thanks in advance.

You may get my usage as below:

CommandLine cmd = new CommandLine("gzip").addArgument("-c").addArgument("/tmp/specificPreffix_2013-11-06.txt").addArgument(">").addArgument("/tmp/specificPreffix_2013-11-06.txt.gz");

OutputStream outputStream = new ByteArrayOutputStream();
DefaultExecutor exec = new DefaultExecutor();
exec.setWatchdog(new ExecuteWatchdog(timeoutInMilliSeconds));
PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream);
exec.setStreamHandler(streamHandler);
exec.execute(cmd);
6
  • I think you'll need a shell in there, to interpret the >. Try running bash through the executor, with -c as the first argument, and the entire string that you're trying to run as the second argument. Commented Apr 3, 2014 at 17:08
  • Thank you David. It doesn't work even if I didn't use >, the code is like this, CommandLine cmd = new CommandLine("bash").addArgument("-c").addArgument("gzip /tmp/specificPreffix_2013-11-06.txt");, something I did wrong? Commented Apr 3, 2014 at 17:30
  • What error are you getting? And have you tried using Runtime.getRuntime().exec( ... ) ? Commented Apr 3, 2014 at 17:59
  • 1
    Hi David, I should found that you have told me the right answer in your first comment earlier, and it works currently, thanks for your help, Runtime.getRuntime().exec(new String[]{"sh","-c","gzip -c /tmp/specificPreffix_2013-11-06.txt > /tmp/specificPreffix_2013-11-06.txt.gz",}); is the correct one. Thank you very much. Commented Apr 3, 2014 at 18:49
  • 1
    OK, no problem. If you've worked out what works, you could post it as an answer here, for the benefit of anyone else having the same problem. I have to admit, I was guessing a bit with my comments, but I'm glad you got there eventually. Commented Apr 3, 2014 at 18:53

2 Answers 2

2
String myActualCommand =
    "gzip -c /tmp/specificPreffix_2013-11-06.txt > /tmp/specificPreffix_2013-11-06.txt.gz";

// able to execute arbitrary shell command sequence
CommandLine shellCommand = new CommandLine("sh").addArgument("-c");

// set handleQuoting = false so our command is taken as it is
shellCommand.addArgument(myActualCommand, false);

Executor exec = new DefaultExecutor();
// ... (configure the executor as you like, e.g. with watchdog and stream handler)

exec.execute(shellCommand);

commons.exec expects the CommadnLine object to represent only one command with arguments for this very command. E.g. echo 'hello world!' is fine but echo 'hello world!' > hello.txt won't work without the workaround I showed above.

Understanding The Workaround

sh -c takes a string with arbitrary shell commands as "an argument" and executes those. From the bash man page:

-c string: If the -c option is present, then commands are read from string. If there are arguments after the string, they are assigned to the positional parameters, starting with $0.

This allows us to pass our shell commands sequence as "an argument", making commons.exec happy. Finally, the false argument in addArgument(...) tells commons.exec to take our actual command as it is.

Sign up to request clarification or add additional context in comments.

Comments

0

The right answer from David@ in comments.

Runtime.getRuntime().exec(new String[]{"sh","-c","gzip -c /tmp/specificPreffix_2013-11-06.txt > /tmp/specificPreffix_2013-11-06.txt.gz",});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.