How to execute a batch script that accepts multiple inputs using Java Process Builder?

I have a script package that accepts input as username and age and prints both inputs. I want to write a java program to execute this script and pass the input.

I wrote a Java program using ProcessBuilder. I also pass in the username and age in the OutputStream process, but only the username is printed and there is no age.

my script (file test.bat):

@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(); } } 
+4
source share
3 answers

So, you clear the two inputs separately from your batch script and close the stream. As a result, the script consumes only the first input. And since the stream is closed then, it simply omits all the remaining SET /P expressions, ignoring the actual inputs remaining in the pipe. And the question is: why?

I found this article that analyzes how the SET /P command works in detail and what conditions exist to end a single input prompt session.

The last 2 char reads are CRLF
This is a normal case and preferred. If the input is not transmitted but entered by the user, the input ends when the ENTER key has been hacked. Then the CRLF tokens were set, and the input is consumed. In our Java channel, we can do the same by adding \r\n to the end of the String . But for some reason this does not work, and I could not understand why. Time-out
A very simple workaround that I could offer you is to just wait a while between the entrances. The result will be that the script consumes each input until the next. Therefore, 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 characters. We can use this to solve this problem by combining a buffer that is equal to char less than 1024. Thus, the first char of the next input will make the buffer full, which will consume the input and move to the next expression. Therefore, if you use this conversion 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 properly. In fact, you can even refuse to rinse.

 OutputStream out = process.getOutputStream(); out.write(convert("tester")); out.write(convert("25")); out.close(); 
+2
source

you can try under the code

 'Runtime runtime = Runtime.getRuntime(); Process proc = null; String executionarr[] = { batchfileName, arg1, arg2}; proc = runtime.exec(executionarr);' 

in your batch file, you can read the first argument with% 1, the second with% 2, etc.

0
source

You can try this code. It works just fine, as someone from stackoverflow also asks this question.

  import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Execute { public static void main(String args[]) { String stream = null; try { Process p = Runtime.getRuntime().exec( "C:\\WINDOWS\\system32\\cmd.exe /c start C:\\src\\test.bat"); BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream())); BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream())); // read the output from the command System.out.println("Here is the standard output of the command:"); while ((stream = stdInput.readLine()) != null) { System.out.println(stream); } // read any errors from the attempted command System.out.println("Here is the standard error of the command (if any):"); while ((stream = stdError.readLine()) != null) { System.out.println(stream); } System.out.println("ended!!"); System.exit(0); } catch (IOException e) { System.out.println("exception happened: "); System.err.println(e.getMessage()); System.exit(-1); } } } 
-1
source

Source: https://habr.com/ru/post/1259039/


All Articles