Я ищу способ получить вывод команды, когда она запускается из программы на C ++. Я смотрел на использование system()
функции, но это будет просто выполнить команду. Вот пример того, что я ищу:
std::string result = system("./some_command");
Мне нужно выполнить произвольную команду и получить ее вывод. Я посмотрел на boost.org , но я не нашел ничего, что дало бы мне то, что мне нужно.
/programming/52164723/how-to-execute-a-command-and-get-return-code-stdout-and-stderr-of-command-in-c
для расширения отличного ответа ниже, который предоставляет методы для полученияreturn code
и,stderr
а также того,stdout
что этот ответ уже объясняетОтветы:
Версия до C ++ 11:
Заменить
popen
иpclose
с_popen
и_pclose
для Windows.источник
result += buffer
, поэтому труба может быть закрыта неправильно.int main(){ puts("ERROR"); }
.Получение как stdout, так и stderr (а также запись в stdin, здесь не показано) очень просто с моим заголовком pstreams , который определяет классы iostream, которые работают следующим образом
popen
:источник
popen
требует использования API-интерфейса C stdio, я предпочитаю API iostreams.popen
требует, чтобы вы вручнуюFILE
очистили ручку, pstreams сделает это автоматически.popen
принимает толькоconst char*
аргумент a , который требует осторожности, чтобы избежать атак внедрения оболочки; pstreams позволяет вам передавать вектор строк, похожих наexecv
, что безопаснее.popen
ничего не дает, кроме канала, pstreams сообщает PID ребенка, позволяющий вам отправлять сигналы, например, чтобы убить его, если он заблокирован или не выходит из него. Все это преимущества, даже если вы хотите только однонаправленный ввод-вывод.pstreambuf::in_avail()
, поэтому блокировать не будет. Это позволяет демультиплексировать на stdout и stderr процесса, поскольку у каждого есть доступные данные.pstreambuf::in_avail()
надежно работает только на 100%, если ОС поддерживает нестандартный FIONREAD ioctl, но поддерживается (по крайней мере) в GNU / Linux и Solaris.Я бы использовал popen () (++ waqas) .
Но иногда вам нужно читать и писать ...
Кажется, что никто не делает вещи трудным путем больше.
(Предполагая среду Unix / Linux / Mac или Windows с уровнем совместимости POSIX ...)
Вы также можете поиграть с select () и неблокирующим чтением.
источник
execlp
вызов содержит ошибку: последнийarg
переданный указатель должен быть(char *) NULL
для правильного завершения списка аргументов с переменным числом аргументов (см.execlp(3)
Ссылку).Для Windows
popen
также работает, но открывает консольное окно, которое быстро вспыхивает над вашим пользовательским интерфейсом. Если вы хотите быть профессионалом, лучше отключить эту «перепрошивку» (особенно, если конечный пользователь может отменить ее).Итак, вот моя собственная версия для Windows:
(Этот код частично объединен с идеями, написанными в проектах The Code Project и MSDN.)
источник
wchar_t
иCreateProcessW
как ненужное ограничение.The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.
поэтому, может быть, лучше сначала скопировать командную строку в отдельный буфер, чтобы предотвратить изменение исходных данных вызывающей стороны.Два возможных подхода:
Я не думаю, что это
popen()
является частью стандарта C ++ (это часть POSIX из памяти), но он доступен на каждом UNIX, с которым я работал (и вы, похоже, ориентируетесь на UNIX, так как ваша команда./some_command
).В случае отсутствия
popen()
, вы можете использоватьsystem("./some_command >/tmp/some_command.out");
, а затем использовать обычные функции ввода-вывода для обработки выходного файла.источник
Следующее может быть портативным решением. Это соответствует стандартам.
источник
tmpnam
опасно, лучше использоватьmkstemp
»Я не мог понять, почему popen / pclose отсутствует в Code :: Blocks / MinGW. Поэтому я решил проблему, используя взамен CreateProcess () и CreatePipe ().
Вот решение, которое сработало для меня:
источник
CREATE_NO_WINDOW
чтоли?ListStdErr
никогда не используется.Предполагая POSIX, простой код для захвата стандартного вывода:
Вклады кода приветствуются для большей функциональности:
https://github.com/ericcurtin/execxx
источник
Вы можете получить результат после запуска сценария с использованием канала. Мы используем каналы, когда хотим получить выход дочернего процесса.
Итак, вот сценарий, который вы хотите запустить. Поместите его в переменную команды с аргументами, которые принимает ваш скрипт (ничего, если нет аргументов). И файл, в который вы хотите захватить вывод скрипта, поместите его в copy_fp.
Поэтому popen запускает ваш скрипт и помещает вывод в fpipe, а затем вы можете просто скопировать все из этого в ваш выходной файл.
Таким образом, вы можете захватить выходные данные дочерних процессов.
И еще один процесс, вы можете напрямую поставить
>
оператор только в команде. Поэтому, если мы поместим все в файл во время выполнения команды, вам не придется ничего копировать.В этом случае нет необходимости использовать трубы. Вы можете использовать just
system
, и он запустит команду и поместит вывод в этот файл.Вы можете прочитать YoLinux Tutorial: Fork, Exec и Process control для получения дополнительной информации.
источник
Обратите внимание, что вы можете получить вывод, перенаправив вывод в файл и затем прочитав его
Это было показано в документации
std::system
Вы можете получить код выхода, вызвав
WEXITSTATUS
макрос.источник