问题
I have a batch script which takes input as user name and age and prints both the inputs. I want to write a java program to execute that script and pass the inputs.
I have written the java program using ProcessBuilder. I am also passing the username and age in the process OutputStream but only user name is getting printed and age is missing.
my script(test.bat file) :
@echo off
echo executing test.bat
set /p name=Enter Name:
set /p age=Enter Age :
echo Hi %name%, you are %age% years old.
my java program :
private static void executeInteractiveCommand(String cmd,String ... args){
try{
List<String> command = new ArrayList<String>();
command.add(cmd);
ProcessBuilder builder = new ProcessBuilder(command);
Map<String, String> environ = builder.environment();
final Process process = builder.start();
OutputStream out = process.getOutputStream();
out.write("tester \n\r".getBytes());
out.flush();
out.write("25\n".getBytes());
out.flush();
out.close();
int errCode = process.waitFor();
System.out.println("Process Error Code : "+errCode);
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
//out.close();
is.close();
System.out.println("Program terminated!");
}catch(IOException ex){
ex.printStackTrace();
} catch(InterruptedException ex){
ex.printStackTrace();
}
}
回答1:
So you flush two inputs separately to your batch script and close the stream. The result is that the script only consumes the first input. And since the stream is closed then, it will simply empty return all remaining SET /P
statements ignoring the real inputs left in the pipe. And the question is: Why?
I found this article that analyses how the SET /P
command works in detail and which conditions exists to end up one running input prompt session.
The last 2 read char are CRLF
This is the normal case and the prefered one. If input is not piped but typed by the user the input is finished when the ENTER key was hitten. Then the CRLF tokens were set and the input gets consumed. In our Java pipe we should be able to do the same by adding \r\n
at the end of String
. But somehow this doesn't work and I could not figure out why.
A timeout
A very simple workaround I could provide you is to simply wait some time between the inputs. The result will be that the script consumes each input before the next. So if you add
Thread.sleep(1000);
between you two inputs everything will work as expected.
full buffer
The input of one SET /P
statement is limited to 1024 chars. We can use this to solve the situation by piping a buffer that is one char smaller than 1024. So the first char of the next input will make the buffer full which will result in consuming the input and going forward to the next statement.
So if you use this convert method
public static byte[] convert(String str){
byte[] asBytes = str.getBytes();
byte[] result = new byte[1023];
for(int i = 0; i < asBytes.length; i++)
result[i] = asBytes[i];
return result;
}
Your code will work as expected. In fact you can even leave out the flushing.
OutputStream out = process.getOutputStream();
out.write(convert("tester"));
out.write(convert("25"));
out.close();
回答2:
you can try below code
'Runtime runtime = Runtime.getRuntime();
Process proc = null;
String executionarr[] = { batchfileName, arg1, arg2};
proc = runtime.exec(executionarr);'
in your batch file, you can read first argument with %1, second with %2 and so on.
来源:https://stackoverflow.com/questions/39913424/how-to-execute-batch-script-which-takes-multiple-inputs-by-using-java-process-bu