23
Process p = Runtime.getRuntime().exec("sh somescript.sh &> out.txt");

I am running this command using Java. The script is running but it's not redirecting its stream to the file. Moreover, the file out.txt is not getting created.

This script runs fine if I run it on shell.

Any ideas?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
user2110167
  • 241
  • 1
  • 3
  • 7
  • why is that ampersand(&) ? – Shashank Kadne Apr 26 '13 at 14:18
  • its for redirecting both output stream as well as error stream to the file – user2110167 Apr 26 '13 at 14:19
  • have you searched your system for the file? – Philipp Sander Apr 26 '13 at 14:21
  • 2
    1) Read the [runtime.exec info. page](http://stackoverflow.com/tags/runtime.exec/info). Implement ***all*** the recommendations in the linked Java World article. 2) Then ignore it refers to `exec` & use a `ProcessBuilder(String[])` constructor. 3) I heard something about pipes not working in a Java process. – Andrew Thompson Apr 26 '13 at 14:22
  • @PhilippSander Yes its not getting created .the command sh somescript.sh is running anyways – user2110167 Apr 26 '13 at 14:23
  • Are you sure it's not being created? Did you check the directory in `System.getProperty("user.dir");` ? – durron597 Apr 26 '13 at 14:24
  • can you be sure that it is not created? maybe it's just not in the directories where you think it should be.... maybe it's in an other directory – Philipp Sander Apr 26 '13 at 14:25
  • 1
    Pipes (and redirects) wouldn't usually work on UNIX because they are things that the shell does. In this case sh is being executed. The behaviour of `Runtime.exec` is largely undocumented. – Tom Hawtin - tackline Apr 26 '13 at 14:27

2 Answers2

46

You need to use ProcessBuilder to redirect.

ProcessBuilder builder = new ProcessBuilder("sh", "somescript.sh");
builder.redirectOutput(new File("out.txt"));
builder.redirectError(new File("out.txt"));
Process p = builder.start(); // may throw IOException
johnchen902
  • 9,531
  • 1
  • 27
  • 69
  • 1
    It works absolutely fine.Thanks ..Are there any references where i can read a bit more about this ,i have to do a lot of things on shell using java.So it will be useful for me – user2110167 Apr 26 '13 at 14:34
  • 1
    @user2110167 [API document about ProcessBuilder](http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html) – johnchen902 Apr 26 '13 at 14:37
  • One More thing, if i want to add some options into the command like somecommand -o "outputdirectory" -i "inputfilelist" ,how can i add -o and -i options? – user2110167 Apr 26 '13 at 14:46
  • @user2110167 `new ProcessBuilder("somecommand", "-o", "outputdirectory", "-i", "inputfilelist");` – johnchen902 Apr 26 '13 at 14:49
  • @johnchen902 I wrote the code as per you have stated .even when we are redirecting both the streams into a file ,there is some output which stays missing .if i run "sh somescript.sh &> out.txt" on shell ,the out.txt file gets each output written by the script,but using process builder and redirecting both the inputs,then it gives output equivalent to writing sh somescript.sh > out.txt .. are we missing anything in the code ..And the script is actually a perl script which calls java functions internally. – user2110167 Apr 26 '13 at 18:01
  • for me can not resolve method redirectOutput and redirectError...:( – AnAndroid Apr 06 '17 at 12:44
  • I would think that it wouldn't work to redirect both output streams to the same file in this way. I would expect two attempts to open the file to occur, and one of them. to fail. Rather, I'd think that you'd specify one and then have a way. of saying to redirect the other one to the one being sent to the file, much like `>blah.out 2>&1`. – CryptoFool Oct 05 '20 at 21:41
  • @johnchen902 , the call to redirectError() should have a different filename than the one for redirectOutput(). Could you change the answer to have this line?: `builder.redirectError(new File("err.txt"));` – UltimateGeek Sep 12 '22 at 11:26
7

When you run a command, there is no shell running and any shell commands or functions are not available. To use something like &> you need a shell. You have one but you are not passing it to it. try instead.

Runtime.getRuntime().exec(new String[] { "sh", "somescript.sh &> out.txt" });
linuxeasy
  • 6,269
  • 7
  • 33
  • 40
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130