Как захватить код выхода и stderr команды, которая выполняется в C ++?

Я пишу программу на C ++, которая выполняет и выводит (в режиме реального времени) сценарий оболочки, make-файл или просто другую программу. Однако я хотел бы, чтобы моя программа возвращалась по-другому, когда есть ошибки или нет ошибок.

#include "execxi.h"using namespace std;int execXI::run(string command)
{

FILE *in;
char buff[512];
// is this the check for command execution exited with not 0?
if(!(in = popen(command.c_str(), "r"))){
// I want to return the exit code and error message too if any
return 1;
}
// this part echoes the output of the command that's executed
while(fgets(buff, sizeof(buff), in)!=NULL){
cout << buff;
}
pclose(in);
return 0;}

это то, что я до сих пор

Допустим, этот скрипт выполнялся make построить программу, и она выдала ошибку, как это так

on_target_webkit_version out/Release/obj/gen/webkit_version.h
Traceback (most recent call last):
File "../build/webkit_version.py", line 107, in <module>
sys.exit(main())
File "../build/webkit_version.py", line 103, in main
return EmitVersionHeader(*sys.argv[1:])
File "../build/webkit_version.py", line 86, in EmitVersionHeader
webkit_revision = GetWebKitRevision(webkit_dir, version_file)
File "../build/webkit_version.py", line 60, in GetWebKitRevision
version_info = lastchange.FetchVersionInfo(
AttributeError: 'module' object has no attribute 'FetchVersionInfo'
make: *** [out/Release/obj/gen/webkit_version.h] Error 1
  • Могу ли я узнать, что это произошло с ошибкой?

    • Это выходит с кодом else than 0 так как это ошибка?

    • Это последняя часть выведена в stderr?

Учитывая, что make выход с кодом не 0скажем 1и вывод в stderr я не могу захватить эти коды выхода и сообщение об ошибке в конце?

Как я могу захватить код выхода и stderr после вывода результатов программы и возврата exit code/ stderr в функции?

15

Решение

Если вас интересует код ошибки, это более переносимый способ его получения, чем деление на 256:

printf("Exit code: %i\n", WEXITSTATUS(pclose(fp)));

Тем не мение, popen Это один из способов, поэтому вы либо создаете дополнительные обходные пути с помощью обычного стиля перенаправления в оболочке, либо вы следуете этому непроверенному коду, чтобы сделать это правильно:

#include <unistd.h>
#include <stdio.h>

/* since pipes are unidirectional, we need two pipes.
one for data to flow from parent's stdout to child's
stdin and the other for child's stdout to flow to
parent's stdin */

#define NUM_PIPES          2

#define PARENT_WRITE_PIPE  0
#define PARENT_READ_PIPE   1

int pipes[NUM_PIPES][2];

/* always in a pipe[], pipe[0] is for read and
pipe[1] is for write */
#define READ_FD  0
#define WRITE_FD 1

#define PARENT_READ_FD  ( pipes[PARENT_READ_PIPE][READ_FD]   )
#define PARENT_WRITE_FD ( pipes[PARENT_WRITE_PIPE][WRITE_FD] )

#define CHILD_READ_FD   ( pipes[PARENT_WRITE_PIPE][READ_FD]  )
#define CHILD_WRITE_FD  ( pipes[PARENT_READ_PIPE][WRITE_FD]  )

void
main()
{
int outfd[2];
int infd[2];

// pipes for parent to write and read
pipe(pipes[PARENT_READ_PIPE]);
pipe(pipes[PARENT_WRITE_PIPE]);

if(!fork()) {
char *argv[]={ "/usr/bin/bc", "-q", 0};

dup2(CHILD_READ_FD, STDIN_FILENO);
dup2(CHILD_WRITE_FD, STDOUT_FILENO);

/* Close fds not required by child. Also, we don't
want the exec'ed program to know these existed */
close(CHILD_READ_FD);
close(CHILD_WRITE_FD);
close(PARENT_READ_FD);
close(PARENT_WRITE_FD);

execv(argv[0], argv);
} else {
char buffer[100];
int count;

/* close fds not required by parent */
close(CHILD_READ_FD);
close(CHILD_WRITE_FD);

// Write to child’s stdin
write(PARENT_WRITE_FD, "2^32\n", 5);

// Read from child’s stdout
count = read(PARENT_READ_FD, buffer, sizeof(buffer)-1);
if (count >= 0) {
buffer[count] = 0;
printf("%s", buffer);
} else {
printf("IO Error\n");
}
}
}

Код отсюда:

http://jineshkj.wordpress.com/2006/12/22/how-to-capture-stdin-stdout-and-stderr-of-child-program/

13

Другие решения

Возвращаемое значение дочернего процесса находится в верхней части 16 8 бит У тебя есть
разделить возвращаемое значение pclose на 256, то вы получите
искали возвращаемое значение дочернего процесса.

Получил от http://bytes.com/topic/c/answers/131694-pclose-returning-termination-status-command

Мой ответ будет pclose(in)/256 это код выхода.

Я до сих пор не знаю, как по-другому захватить stderr или sdtout, но пока не будет ответа, я приму это как свой ответ.

9

Спасибо за ответ по поводу кода выхода Логана.

Я считаю, что в оба конца можно получить перенаправление во временный файл:

FILE* f = popen("cmd 2>/tmp/tmpfile.txt", "r");
1
По вопросам рекламы [email protected]