Первые три строки всегда выводятся на стандартный вывод, за ними следует строка использования, выводимая на стандартный вывод. cmd.exe — это оболочка-интерпретатор, которая запускает процесс cl.exe, считывает из него stderr/stdout и выводит текст на вывод консоли. Он всегда выводит его в этом порядке, никогда не появляясь перед stderr (возможно, они выполняют fflush(stderr) перед печатью строки использования).
Если я использую boost: :process что бы я ни пробовал, порядок вывода почти всегда не соответствовал тому, что показывал cmd.exe.
Я использую этот пример программы для вывода вывода:
/// test-exe.exe
#include
#include
int main()
{
int lineLen = 1024;
int stdoutCount = 5;
int stderrCount = 5;
int repeatCount = 10;
std::string s;
s.resize(lineLen);
for (int i = 0; i < lineLen; ++i)
s = '0' + (i / 10) % 10;
int n = 0;
for (int i = 0; i < repeatCount; ++i)
{
for (int i = 0; i < stdoutCount; ++i)
fprintf(stdout, "stdout %d %s\n", n++, s.c_str());
for (int i = 0; i < stderrCount; ++i)
fprintf(stderr, "stderr %d %s\n", n++, s.c_str());
}
}
Как правильно это сделать с помощью boost::process::child, чтобы объединенный вывод соответствовал тому, что отображается в обычном приглашении cmd?
Один из способов — использовать boost:: process::system и перенаправить stderr на stdout (например, system("test.exe 2>&1")), но это обходной путь, поскольку потоки обрабатываются с помощью cmd.exe под капотом, и я объединяюсь stdout без какого-либо различия, является ли что-то стандартным выводом или stderr.
Я использовал этот код в качестве отправной точки и пытался изменить его по-разному, но у меня это не сработало. Он не получает тупиковые строки чтения из stdout/stderr, но порядок вывода не сохраняется так, как его получает cmd.exe.
#include
#include
#include
#include
struct OutputLine
{
std::string data; // with trailing /r/n stripped if any
bool isStderr; // if the line is stderr
};
static int getCmdOutput(const char* cmd, std::vector& out)
{
namespace bp = boost::process;
Вот пример вывода компилятора MS: [img]https://i.sstatic.net/pBIN38Cf.png[/img]
Первые три строки всегда выводятся на стандартный вывод, за ними следует строка использования, выводимая на стандартный вывод. cmd.exe — это оболочка-интерпретатор, которая запускает процесс cl.exe, считывает из него stderr/stdout и выводит текст на вывод консоли. Он всегда выводит его в этом порядке, никогда не появляясь перед stderr (возможно, они выполняют fflush(stderr) перед печатью строки использования). Если я использую boost: :process что бы я ни пробовал, порядок вывода почти всегда не соответствовал тому, что показывал cmd.exe. Я использую этот пример программы для вывода вывода: /// test-exe.exe #include #include
int main() { int lineLen = 1024; int stdoutCount = 5; int stderrCount = 5; int repeatCount = 10;
std::string s; s.resize(lineLen); for (int i = 0; i < lineLen; ++i) s[i] = '0' + (i / 10) % 10;
int n = 0;
for (int i = 0; i < repeatCount; ++i) { for (int i = 0; i < stdoutCount; ++i) fprintf(stdout, "stdout %d %s\n", n++, s.c_str()); for (int i = 0; i < stderrCount; ++i) fprintf(stderr, "stderr %d %s\n", n++, s.c_str()); } }
Как правильно это сделать с помощью boost::process::child, чтобы объединенный вывод соответствовал тому, что отображается в обычном приглашении cmd? Один из способов — использовать boost:: process::system и перенаправить stderr на stdout (например, system("test.exe 2>&1")), но это обходной путь, поскольку потоки обрабатываются с помощью cmd.exe под капотом, и я объединяюсь stdout без какого-либо различия, является ли что-то стандартным выводом или stderr. Я использовал этот код в качестве отправной точки и пытался изменить его по-разному, но у меня это не сработало. Он не получает тупиковые строки чтения из stdout/stderr, но порядок вывода не сохраняется так, как его получает cmd.exe. #include #include #include #include
struct OutputLine { std::string data; // with trailing /r/n stripped if any bool isStderr; // if the line is stderr };
static int getCmdOutput(const char* cmd, std::vector& out) { namespace bp = boost::process;