Вопрос

Как мне запустить приложение и записать вывод через stdout и, возможно, stderr?

Я пишу автоматизированную систему сборки, и мне нужно записать результаты для анализа. Я хотел бы обновить репозиторий SVN и получить номер ревизии, чтобы я мог переместить файлы в autobuild / revNumber / в случае успеха. Я также хотел бы собрать с помощью make и загрузить текст компиляции на мой сервер, чтобы все могли видеть предупреждения и ошибки при неудачной сборке.

Я не могу найти функцию system () , но я обнаружил функцию CreateProcess () в MSDN. Я могу запустить то, что мне нужно, но я не знаю, как захватить stderr и stdout. Я замечаю, что процесс запускается отдельно, если я не установлю точку останова и продолжу выход из моего приложения, после чего он сохранит весь текст в окне консоли приложения. Я также хотел бы подождать, пока все процессы не будут завершены, а затем просканировать полученные данные, чтобы выполнить любые дополнительные операции, которые мне нужны. Как мне это сделать?

Это было полезно?

Решение

В реальных оболочках (то есть не в морских оболочках - я имею в виду, не в C Shell или его производных), то

program arg1 arg2 >/tmp/log.file 2>&1

Это запускает программу с заданными аргументами и перенаправляет стандартный вывод в /tmp/log.file; запись ( иероглиф ) ' 2 > & amp; 1 ' в конце отправляет stderr (дескриптор файла 2) в то же место, куда идет stdout (дескриптор файла 1). Обратите внимание, что последовательность операций важна; если вы измените их, то стандартная ошибка будет идти туда, куда шел стандартный вывод, а затем стандартный вывод (но не стандартная ошибка) будет перенаправлен в файл.

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

LOG=${TMPDIR:-/tmp}/log.$.$(date +%Y%m%d-%H%M%S)
program arg1 arg2 >$LOG 2>&1

В C ++ вы можете использовать функцию system () (унаследованную от C) для запуска процессов. Если вам необходимо знать имя файла в программе на C ++ (правдоподобно), то сгенерируйте имя в программе ( strftime () - ваш друг) и создайте командную строку с этим именем файла. (Строго говоря, вам также нужно getenv () , чтобы получить $ TMPDIR, и функцию POSIX getpid () , чтобы получить идентификатор процесса, а затем вы можете смоделировать двухстрочный сценарий оболочки (хотя используемый PID относится к программе C ++, а не к запущенной оболочке).

Вместо этого вы можете использовать функцию POSIX popen () ; вам нужно будет включить нотацию 2 > & amp; 1 в создаваемую вами командную строку, чтобы отправить стандартную ошибку команды в то же место, куда идет стандартный вывод, но вы бы этого не сделали нужен временный файл:

FILE *pp = popen("program arg1 arg2 2>&1", "r");

Затем вы можете прочитать поток файла. Я не уверен, есть ли чистый способ отобразить поток файлов C в istream C ++; там, вероятно, есть.

Другие советы

Вам необходимо заполнить структуру STARTUP_INFO, в которой есть hStdInput, hStdOutput и hStdError. Не забудьте наследовать дескрипторы при создании CreateProcess.

/* Assume you open a file handle or pipe called myoutput */
STARTUP_INFO si_startinfo;
ZeroMemory(&si_startinfo, sizeof(STARTUP_INFO));
si_startinfo.cb = sizeof(STARTUP_INFO);
si_startinfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
si_startinfo.hStdOutput = myoutput;
si_startinfo.hStdError = myoutput;
si_startifno.dwFlags != STARTF_USEHANDLES;

PROCESS_INFORMATION pi_procinfo;
ZeroMemory(&pi_procinfo, sizeof(PROCESS_INFORMATION);

CreateProcess(NULL, cmdline, NULL, NULL, true, 0, NULL, pathname, &si_startinfo, &pi_procinfo);

Я не показал аспекты обработки ошибок, которые вам нужно будет сделать. 5-й аргумент устанавливается в true, чтобы наследовать дескрипторы. Другие объясняли, как создавать трубы, поэтому я не буду повторять это здесь.

ЭЛТ Microsoft и библиотека MSDN включают в себя системную функцию и функцию _popen.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top