sirve que pause para library c++ c system stdout

que - system h c++



Captura de stdout de un comando de sistema() de forma óptima (10)

Esta pregunta ya tiene una respuesta aquí:

Estoy intentando iniciar una aplicación externa a través de system() ; por ejemplo, system("ls") . Me gustaría capturar su salida a medida que sucede, así puedo enviarla a otra función para su posterior procesamiento. ¿Cuál es la mejor manera de hacerlo en C / C ++?


Del manual de popen:

#include <stdio.h> FILE *popen(const char *command, const char *type); int pclose(FILE *stream);


EDITAR: leyó mal la pregunta por querer pasar la salida a otro programa, no a otra función. popen () es casi seguramente lo que quieres.

El sistema le da acceso total al shell. Si desea continuar usándolo, puede redirigir su salida a un archivo temporal, por sistema ("ls> tempfile.txt"), pero elegir un archivo temporal seguro es un problema. O bien, puede incluso redirigirlo a través de otro programa: system ("ls | otherprogram");

Algunos pueden recomendar el comando popen (). Esto es lo que quiere si puede procesar la salida usted mismo:

FILE *output = popen("ls", "r");

que le dará un puntero ARCHIVO desde el que puede leer con el resultado del comando.

También puede usar la llamada pipe () para crear una conexión en combinación con fork () para crear nuevos procesos, dup2 () para cambiar la entrada y salida estándar de ellos, exec () para ejecutar los nuevos programas y wait () en el programa principal para esperarlos. Esto simplemente está configurando la tubería de manera similar a como lo haría el caparazón. Consulte la página man de pipe () para obtener detalles y un ejemplo.


En Windows, en lugar de usar system (), use CreateProcess, redirija la salida a una tubería y conéctese a la tubería.

¿Supongo que esto también es posible de alguna manera POSIX?


En esta página: capture_the_output_of_a_child_process_in_c describe las limitaciones del uso de popen frente al enfoque fork / exec / dup2 / STDOUT_FILENO.

Tengo problemas para capturar la producción de tshark con popen .

Y supongo que esta limitación podría ser mi problema:

Devuelve una secuencia stdio en lugar de un descriptor de archivo sin formato, que no es adecuado para manejar la salida de forma asincrónica.

Volveré a esta respuesta si tengo una solución con el otro enfoque.


En realidad, acabo de verificar y:

  1. popen es problemático, porque el proceso se bifurca. Entonces, si necesita esperar a que se ejecute el comando de shell, entonces está en peligro de perderlo. En mi caso, mi programa se cerró incluso antes de que la tubería hiciera su trabajo.

  2. Terminé usando la llamada al sistema con el comando tar en Linux. El valor de retorno del sistema fue el resultado de tar .

Entonces, si necesita el valor de retorno , no solo no es necesario usar popen, probablemente no hará lo que usted quiere.


La forma más eficiente es usar el descriptor de archivo stdout directamente, evitando el flujo de archivos:

pid_t popen2(const char *command, int * infp, int * outfp) { int p_stdin[2], p_stdout[2]; pid_t pid; if (pipe(p_stdin) == -1) return -1; if (pipe(p_stdout) == -1) { close(p_stdin[0]); close(p_stdin[1]); return -1; } pid = fork(); if (pid < 0) { close(p_stdin[0]); close(p_stdin[1]); close(p_stdout[0]); close(p_stdout[1]); return pid; } else if (pid == 0) { close(p_stdin[1]); dup2(p_stdin[0], 0); close(p_stdout[0]); dup2(p_stdout[1], 1); dup2(::open("/dev/null", O_WRONLY), 2); /// Close all other descriptors for the safety sake. for (int i = 3; i < 4096; ++i) { ::close(i); } setsid(); execl("/bin/sh", "sh", "-c", command, NULL); _exit(1); } close(p_stdin[0]); close(p_stdout[1]); if (infp == NULL) { close(p_stdin[1]); } else { *infp = p_stdin[1]; } if (outfp == NULL) { close(p_stdout[0]); } else { *outfp = p_stdout[0]; } return pid; }

Para leer el resultado del uso infantil popen2() esta manera:

int child_stdout = -1; pid_t child_pid = popen2("ls", 0, &child_stdout); if (!child_pid) { handle_error(); } char buff[128]; ssize_t bytes_read = read(child_stdout, buff, sizeof(buff));

Para escribir y leer:

int child_stdin = -1; int child_stdout = -1; pid_t child_pid = popen2("grep 123", &child_stdin, &child_stdout); if (!child_pid) { handle_error(); } const char text = "1/n2/n123/n3"; ssize_t bytes_written = write(child_stdin, text, sizeof(text) - 1); char buff[128]; ssize_t bytes_read = read(child_stdout, buff, sizeof(buff));


Las funciones popen() y pclose() podrían ser lo que estás buscando.

Eche un vistazo al manual de glibc para ver un ejemplo.


Las funciones popen() y tal no redireccionan stderr y tal; Escribí popen3() para ese propósito.


No estoy del todo seguro de que sea posible en el estándar C, ya que dos procesos diferentes normalmente no comparten espacio de memoria. La forma más sencilla en que se me ocurre hacerlo es hacer que el segundo programa redirija su salida a un archivo de texto (nombre de programa> archivo de texto.txt) y luego volver a leer ese archivo de texto para procesarlo. Sin embargo, esa puede no ser la mejor manera.


Pruebe la función popen (). Ejecuta un comando, como system (), pero dirige el resultado a un nuevo archivo. Se devuelve un puntero a la secuencia.

FILE *lsofFile_p = popen("lsof", "r"); if (!lsofFile_p) { return -1; } char buffer[1024]; char *line_p = fgets(buffer, sizeof(buffer), lsofFile_p); pclose(lsofFile_p);