Невозможно прочитать вывод программы, используя как STDIN, так и STDERR в Java - PullRequest
1 голос
/ 13 мая 2019

Я пытаюсь прочитать вывод sam-ba.exe (который загружает код в микроконтроллеры ARM через USB) в мою Java-программу.При написании этой точной команды в командной строке:

"sam-ba_3.2.1\sam-ba.exe" -p usb -d SAME70 -a internalflash

Результат:

Error: No serial ports found

Но при выполнении этой команды в следующем Java-коде из также ничего не возвращается стандартный вывод или стандартные потоки ошибок (см. Следующее):

Command executed: "sam-ba_3.2.1\sam-ba.exe" -p usb -d SAME70 -a internalflash
Here is the standard output of the command:

Here is the standard error of the command (if any):

Что делает более раздражающим то, что замена этой команды в коде Java будет возвращать информацию в потоке stderr:

"sam-ba_3.2.1\sam-ba.exe" --help

Результат:

Here is the standard output of the command:

Here is the standard error of the command (if any):

SAM-BA Command Line Tool v3.2.1
Copyright 2015-2017 ATMEL Corporation

Usage: sam-ba_3.2.1\sam-ba.exe [options]

Options:
  -v, --version                          Displays version information.
  -h, --help                             Displays this help.
  -t, --tracelevel <trace_level>         Set trace level to <trace_level>.
  -x, --execute <script.qml>             Execute script <script-file>.
  -p, --port <port[:options:...]>        Communicate with device using <port>.
  -d, --device <device[:options:...]>    Connected device is <device>.
  -b, --board <board[:options:...]>      Connected board is <board>.
  -m, --monitor <command[:options:...]>  Run monitor command <command>.
  -a, --applet <applet[:options:...]>    Load and initialize applet <applet>.
  -c, --command <command[:args:...]>     Run command <command>.

В консоли я попытался перенаправить вывод первой (нерабочей) команды в текстовый файл, и в текстовом файле отображается ожидаемая ошибка №последовательные порты, но только если используется следующая команда:

"sam-ba_3.2.1\sam-ba.exe" -p usb -d SAME70 -a internalflash > output.txt 2>&1

Это заставляет меня поверить, что сообщение исходит от stderr, потому что если я опущу "2> & 1", текстовый файл будет пустым.Но тогда почему stderr в программе Java пуст?

Вот мой код Java:

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.BufferedReader;

public class ProcessDemo {

   public static void main(String[] args) {
        try
        {
            Runtime r = Runtime.getRuntime();
            //String command = "\"sam-ba_3.2.1\\sam-ba.exe\" --help";
            String command = "\"sam-ba_3.2.1\\sam-ba.exe\" -p usb -d SAME70 -a internalflash";

            System.out.println("Command executed: " + command);

            Process proc = r.exec(command);

            BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));

            // read the output from the command
            System.out.println("Here is the standard output of the command:\n");
            String s = null;
            while ((s = stdInput.readLine()) != null) {
                System.out.println(s);
            }

            // read any errors from the attempted command
            System.out.println("Here is the standard error of the command (if any):\n");

            while ((s = stdError.readLine()) != null) {
                System.out.println(s);
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

Любая помощь будет отличной,

Judd

Обновление: Как и предполагалось, я сейчас использую ProcessBuilder и удалил кавычки, но результат точно такой же.

Было предложено добавить Redirect.INHERIT, как показано, но это приводит кследующий вывод.Похоже, он просто обходит входные потоки и идет прямо к терминалу?

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.BufferedReader;


public class ProcessDemo {

   public static void main(String[] args) {

        try
        {
            // String[] command = {"sam-ba_3.2.1\\sam-ba.exe","--help"};
            String[] command = {"sam-ba_3.2.1\\sam-ba.exe", "-p", "usb", "-d", "SAME70", "-a", "internalflash", "-c", "write:\"GCCBoardProject1.bin\""};
            ProcessBuilder pb = new ProcessBuilder(command);
            pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
            pb.redirectError(ProcessBuilder.Redirect.INHERIT);

            Process proc = pb.start();
            proc.waitFor();

            BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));

            System.out.println("Here is the standard output of the command:\n");

            // read the output from the command
            String s = null;
            while ((s = stdInput.readLine()) != null)
            {
                System.out.println(s);
            }

            // read any errors from the attempted command
            System.out.println("Here is the standard error of the command (if any):\n");

            while ((s = stdError.readLine()) != null)
            {
                System.out.println(s);
            }

            System.out.println("return value: " + proc.exitValue());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

Вывод:

Error: No serial ports found
Here is the standard output of the command:

Here is the standard error of the command (if any):

return value: -1

Ответы [ 2 ]

0 голосов
/ 13 мая 2019

Проблема, похоже, является командой, которую вы передаете, когда я использую mysqld start в аргументах командной строки процесса вашей программы.Я могу видеть выход.Так что проблема с командой CLI, которую вы передаете.Предложение Запустите его вручную и посмотрите распечатанный результат.

String[] command = {"C:\\Users\\userid\\Downloads\\mysql-5.7.13-winx64\\mysql-5.7.13-winx64\\bin\\mysqld.exe", "--console"};  

Пример вывода:

    C:\Users\userid\other\stk-overflow>java ProcessDemo



   2019-05-13T00:57:04.191518Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
    2019-05-13T00:57:04.191518Z 0 [Warning] 'NO_AUTO_CREATE_USER' sql mode was not set.
    2019-05-13T00:57:04.191518Z 0 [Warning] Insecure configuration for --secure-file-priv: Current value does not restrict location of generated files. Consider setting it to a valid, non-empty path.
    2019-05-13T00:57:04.191518Z 0 [Note] C:\Users\userid\Downloads\mysql-5.7.13-winx64\mysql-5.7.13-winx64\bin\mysqld.exe (mysqld 5.7.13) starting as process 21604 ...
    2019-05-13T00:57:04.201520Z 0 [Note] InnoDB: Mutexes and rw_locks use Windows interlocked functions
    2019-05-13T00:57:04.202742Z 0 [Note] InnoDB: Uses event mutexes
    2019-05-13T00:57:04.203516Z 0 [Note] InnoDB: _mm_lfence() and _mm_sfence() are used for memory barrier
    2019-05-13T00:57:04.203516Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.3
    2019-05-13T00:57:04.204517Z 0 [Note] InnoDB: Number of pools: 1
    2019-05-13T00:57:04.205519Z 0 [Note] InnoDB: Not using CPU crc32 instructions
    2019-05-13T00:57:04.209518Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
0 голосов
/ 13 мая 2019

proc.waitFor (); Этот оператор должен появляться перед оператором BufferedReader и передаваться как в считывателе входного потока. Примечание. Метод Process.waitFor () приостанавливает текущий поток до тех пор, пока процесс не сможет завершиться. Затем с помощью BufferReader вы можете прочитать вывод.

Ссылка: Захват вывода внешней программы в формате JAVA

...