Как выполнить пакетный скрипт, который принимает несколько входных данных с помощью Java Process Builder?

#java #processbuilder

#java #processbuilder

Вопрос:

У меня есть пакетный скрипт, который принимает входные данные в виде имени пользователя и возраста и печатает оба входных данных. Я хочу написать Java-программу для выполнения этого скрипта и передачи входных данных.

Я написал Java-программу с помощью ProcessBuilder. Я также передаю имя пользователя и возраст в поток вывода процесса, но печатается только имя пользователя, а возраст отсутствует.

мой скрипт (файл 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.
  

моя Java-программа :

 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 nr".getBytes());
            out.flush();

            out.write("25n".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. вот результат: код ошибки процесса java TestScript: 0 выполнение теста.bat Введите имя: Введите возраст: Привет, тестировщик, тебе много лет. Программа завершена!

Ответ №1:

Таким образом, вы сбрасываете два входа отдельно в свой пакетный скрипт и закрываете поток. В результате скрипт использует только первый ввод. И поскольку поток тогда закрыт, он просто пусто вернет все оставшиеся SET /P операторы, игнорируя реальные входные данные, оставшиеся в канале. И вопрос: почему?

Я нашел эту статью, в которой подробно анализируется, как SET /P работает команда, и какие условия существуют для завершения одного сеанса ввода запроса.

Последние 2 прочитанных символа — CRLF
Это обычный случай и предпочтительный. Если ввод не передается по каналу, а вводится пользователем, ввод завершается при нажатии клавиши ввода. Затем были установлены токены CRLF, и входные данные будут использованы. В нашем Java-канале мы должны быть в состоянии сделать то же самое, добавив rn в конце String . Но почему-то это не работает, и я не мог понять, почему.

Тайм-аут
Очень простой обходной путь, который я мог бы вам предоставить, — это просто подождать некоторое время между вводами. Результатом будет то, что скрипт использует каждый ввод перед следующим. Поэтому, если вы добавите

 Thread.sleep(1000);
  

между вашими двумя входами все будет работать так, как ожидалось.

полный буфер
Ввод одного SET /P оператора ограничен 1024 символами. Мы можем использовать это, чтобы решить ситуацию, передав буфер размером на один символ меньше 1024. Таким образом, первый символ следующего ввода заполнит буфер, что приведет к потреблению входных данных и переходу к следующему оператору. Итак, если вы используете этот метод преобразования

 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 resu<
}
  

Ваш код будет работать так, как ожидалось. На самом деле вы даже можете не выполнять очистку.

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

Комментарии:

1. Спасибо за вашу помощь. после перевода в режим ожидания я получаю желаемый результат.

2. @RajeshKumar На самом деле да. Я провел некоторое исследование. Смотрите мое редактирование.

Ответ №2:

вы можете попробовать приведенный ниже код

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

в вашем пакетном файле вы можете прочитать первый аргумент с %1, второй с %2 и так далее.