aspose file tools*
The moose likes Java in General and the fly likes Runtime.getRuntime().exec(commandToExecute) without promting for enter key to be pressed Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Runtime.getRuntime().exec(commandToExecute) without promting for enter key to be pressed" Watch "Runtime.getRuntime().exec(commandToExecute) without promting for enter key to be pressed" New topic
Author

Runtime.getRuntime().exec(commandToExecute) without promting for enter key to be pressed

Sg Ramkumar
Greenhorn

Joined: Jun 21, 2010
Posts: 5
Hi,

I'm having a shell script that is to be invoked from a java program.
The shell script is like:
# /tmp/a.sh
#!/bin/sh
read a
echo "this is the next line"


I want the java program to execute this shell script without prompting for "enter key" to be pressed

String commandToExecute = "sh /tmp/a.sh";
Process p = Runtime.getRuntime().exec(commandToExecute);

The above 2 lines are part of my java program. Executing the above java code hangs waiting for input.
Need help on getting the java code lines to automatically accept enter key and go next on the shell script
James Sabre
Ranch Hand

Joined: Sep 07, 2004
Posts: 781

Open the Process stdin (Process.getOutputStream() ) and write the desired bytes. Depending on the detail of what you are doing you may need to write an end-of-line and then to flush() or close() the stdin stream.


Retired horse trader.
 Note: double-underline links may be advertisements automatically added by this site and are probably not endorsed by me.
Seetharaman Venkatasamy
Ranch Hand

Joined: Jan 28, 2008
Posts: 5575

precausion : Daconta's article
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19784
    
  20

This thread is very similar to this one.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Sg Ramkumar
Greenhorn

Joined: Jun 21, 2010
Posts: 5
Thanks guys for the answers. It was greatly helpful.

I used the following code:

try {
Runtime rt = Runtime.getRuntime();
String[] cmd = {"/bin/bash", "-c", "myscript.sh"};
System.out.println("Command to execute: " + cmd);
Process pr = rt.exec(cmd);
System.out.println("Pausing 10 sec...");
Thread.sleep(10000);
System.out.println("Pausing 10 sec... done");
OutputStream stdin = pr.getOutputStream();
String carriageReturn = "\n";
stdin.write(carriageReturn.getBytes() );
stdin.flush();
stdin.close();

BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()));

String line=null;

while((line=input.readLine()) != null) {
// System.out.println(line);
}

int exitVal = pr.waitFor();
System.out.println("Exited with error code "+exitVal);

} catch(Exception e) {
System.out.println(e.toString());
e.printStackTrace();
}
James Sabre
Ranch Hand

Joined: Sep 07, 2004
Posts: 781

You need to handle the Process stderr stream as recommended in the 'traps' article cited earlier by Seetharaman Venkatasamy. You might get away without handling stderr this time but at some point in this project or the next it will jump up and bite you. If you are just discarding the Process stdout then you can either use ProcessBuilder rather than Runtime.exec() and merge stderr into stdout using ProcessBuilder.redirectErrorStream(true) or you can perform the merge within the shell by appending 2>&1 to your command.

Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19784
    
  20

James Sabre wrote:or you can perform the merge within the shell by appending 2>&1 to your command.

Except that the JVM will act as a shell for the newly launched process. Things like piping (using | to send output from one process as input to a next), || and && (conditional execution of a second process) and stream redirecting cannot be handled by passing that to Runtime.exec() or ProcessBuilder. You'll need to implement those yourself.

Sure, you can use redirecting for the JVM itself but I'm not sure that will be propagated to the launched process. I much prefer your redirecting with ProcessBuilder suggestion.
James Sabre
Ranch Hand

Joined: Sep 07, 2004
Posts: 781

Rob Prime wrote:
James Sabre wrote:or you can perform the merge within the shell by appending 2>&1 to your command.

Except that the JVM will act as a shell for the newly launched process. Things like piping (using | to send output from one process as input to a next), || and && (conditional execution of a second process) and stream redirecting cannot be handled by passing that to Runtime.exec() or ProcessBuilder. You'll need to implement those yourself.

Sure, you can use redirecting for the JVM itself but I'm not sure that will be propagated to the launched process. I much prefer your redirecting with ProcessBuilder suggestion.


Sorry but I have to disagree. I have just run

which runs the script test.sh using the CWD as $HOME and sends all the stdout from the script test.sh to stderr.

Without the "cd $HOME" the script runs using a CWD of where I execute the java from i.e. "$HOME/work/dev/projects/scratch" and fails since it relies on finding a specfic directory in the CWD. With the "cd $HOME" the script runs as expected. The redirection of stdout to stderr works just as expected.

The important point is that the "-c" says take the next argument as a bash script and this script can contain just about anything that is a valid shell script. The pipe ('|') and background ('&') and conditional operators ('||' and '&&') and redirection all work as one would expect. There may be limitations but I have never come across any and I have used Runtime.exec() with bash and csh for many years.

On Windows using cmd.exe things are very different but the OP is dealing with sh.




Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19784
    
  20

You're absolutely right; I missed the fact that the JVM was starting a new shell.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Runtime.getRuntime().exec(commandToExecute) without promting for enter key to be pressed