2012-10-24 17 views
5

Próbuję napisać program, który uruchamia zewnętrzny program.Złap stderr i stdout z zewnętrznego programu w C++

wiem, że mogę złapać stdout i mogę złapać stdout i stderr razem, ale pytanie brzmi mogę złapać stderr i stdout rozdzielić?

Mam na myśli na przykład stderr w zmiennej STDERR i stdout w zmiennej STDOUT. Chodzi mi o to, że chcę je rozdzielić.

Potrzebuję również kodu wyjścia programu zewnętrznego w zmiennej.

+3

Jaki system operacyjny? A jakie podejście "znasz", aby je połączyć? – ybungalobill

+0

Używam Ubuntu i wiem, że mogę używać 2> i 1. Ale chcę je rozdzielić. Dzięki –

+0

Spójrz na tę odpowiedź: http://stackoverflow.com/a/12839498/1741542 –

Odpowiedz

2

W systemie Windows należy wpisać STARTUPINFO dla CreateProcess, aby przechwycić standardowe strumienie i można użyć funkcji GetExitCodeProcess, aby uzyskać status zakończenia. Jest to przykład jak przekierować Standart strumienie do procesu macierzystego http://msdn.microsoft.com/en-us/library/windows/desktop/ms682499.aspx

Na Linux-like OS prawdopodobnie chcesz użyć fork zamiast execve i pracy z rozwidloną procesu jest inna historia.

W systemach Windows i Linux strumienie przekierowań mają ogólne podejście - należy utworzyć kilka potoków (po jednym dla każdego strumienia) i przekierować strumienie procesów potomnych do tych rur, a proces macierzysty może odczytać dane z tych potoków.

Przykładowy kod dla Linuksa:

int fd[2]; 

if (pipe(fd) == -1) { 
    perror("pipe"); 
    exit(EXIT_FAILURE); 
} 

pid_t cpid = fork(); 
if (cpid == -1) { 
    perror("fork"); 
    exit(EXIT_FAILURE); 
} 

if (cpid == 0) { // child 
    dup2(fd[1], STDERR_FILENO); 
    fprintf(stderr, "Hello, World!\n"); 
    exit(EXIT_SUCCESS); 
} else { // parent 
    char ch; 
    while (read(fd[0], &ch, 1) > 0) 
     printf("%c", ch); 
    exit(EXIT_SUCCESS); 
} 

EDIT: Jeśli trzeba złapać strumieni z innego programu, należy użyć tego samego stragey jak wyżej, pierwszy fork, drugi - rury użytkowania (jak w powyższym kodzie) , następnie execve inny Progrram w procesie potomnym i użyć tego kodu w procesie macierzystym czekać kres wykonania i złapać kod zwrotny:

int status; 
if (waitpid(cpid, &status, 0) < 0) { 
    perror("waitpid"); 
    exit(EXIT_FAILURE); 
} 

można znaleźć więcej szczegółów na stronach man pipe, dup2 i waitpid.

Powiązane problemy