Как выполнить несколько команд для существующего процесса bash? - PullRequest
0 голосов
/ 20 марта 2020

Я делаю простой GUI интерфейс для сервера TUI Minecraft, мне нужно давать команды этой программе на основе событий GUI (нажатие кнопки и c ...). Я создал компоновщик процессов, но как бы я дал работающей программе больше команд.

Примером того, что я пытаюсь выполнить sh, является открытие программы командной строки в Java, и программа запрашивает для моего имени. У меня вопрос: как мне дать этой программе свое имя?

Я просмотрел множество ранее существовавших сообщений Stack-exchange * о похожих вещах, но ни один из них не работает для меня.

Я такой linux кстати, если это важно.

public Process runCommand(String command) throws IOException {
        ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", command, "-S");

        Process process = pb.start(); // Executes the command
        return process;
    }

    public void showCommandOutput(Process process) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); 

        String line = ""; // Empty String to put the output in
        try {
            while ((line = reader.readLine()) != null) { // For every line in the shell output
                System.out.println(line); // Print the line
            }
            try {
                process.waitFor();
            } catch (InterruptedException e) {
                e.printStackTrace(); // If this goes wrong, display stack trace
            } finally {
                quitServer(0); // External function for closing program, self explanatory
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Заранее спасибо.

1 Ответ

0 голосов
/ 20 марта 2020

Вы уже на полпути. Объект Process, который возвращается при вызове pb.start(), содержит входной и выходной потоки, необходимые для взаимодействия с внешней программой. Вы уже читаете из process.getInputStream(), чтобы получить вывод процесса. Чтобы отправить его на вход, вам просто нужно записать данные в поток process.getOutputStream().

Вам следует остерегаться при использовании readLine() с процессом, подобным bash. Когда bash выводит командную строку, она не завершает ее новой строкой (поэтому вы можете ввести свою команду в той же строке). Так что ваш readLine() будет ждать вечно новой строки, которая не придет. Возможно, вы захотите использовать небуферизованные операции чтения и проверить данные на наличие чего-либо, похожего на приглашение.

Если вы точно знаете, что ваша программа будет выводить текст, ожидать ответ, а затем читать на вводе, вы можете выполните это в вашем существующем l oop. Предоставление команды после прочтения каждой обнаруженной строки является подсказкой. Например:

    PrintStream commandWriter = new PrintStream(process.getOutputStream());
    while ((line = reader.read()) != null) { // For every line in the shell output
      // if I know prompts end with a certain substring
      if (line.endsWith("$> ")) {
        commandWriter.println("echo \"this is a command I sent to a process\"");
      }
      else {
        System.out.println("Received from process: " + line);
      }
    }

Но если программа, с которой вы взаимодействуете, более интерактивна, вы, вероятно, захотите запустить отдельные потоки для чтения и записи ввода / вывода. Вы должны быть осторожны с процессами, чтобы убедиться, что вы продолжаете читать данные из них, когда они доступны. Если вы забудете это сделать, внешняя программа может зависнуть, если она застрянет в полном буфере.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...