2012-06-25 55 views
5

En este programa C¿Cómo redirigir la salida del sistema() a un archivo?

#include <stdio.h> 
#include <fcntl.h> 
int main() 
{ 
    int file = open("Result", O_CREAT|O_WRONLY, S_IRWXU); 

    dup2(stdout, file); 
    system("ls -l"); 

    return 0; 
} 

estoy tratando de reorientar la salida de system() a un archivo, por que he utilizado dup2 pero no está funcionando.

¿Qué pasa con este código?
y, por favor dígame si hay alguna forma mejor de hacerlo? (sin usar > en el terminal)

+3

Por qué no sólo tiene que utilizar el '>' 'redirección en el comando system'? –

+0

Usa 'system (" ls -l> Result ");' o crea tu propia combinación 'fork()'/'exec *()'. –

+1

No use 'system'. Siempre está mal. Ejecute el proceso secundario usted mismo sin un shell, ya sea usando 'fork' y' execvp' o 'posix_spawn'. –

Respuesta

4

stdout es un puntero FILE * del flujo de salida estándar. dup2 espera el descriptor de archivo, también ha alterado el orden de los parámetros. Utilice

dup2(file, 1); 

en su lugar.

En la mejor manera de hacerlo, esta parte. De esta manera es malo porque probablemente desee restaurar su salida estándar después de que se complete esta llamada system. Puedes hacer esto de varias formas. Puede dup en algún lugar y luego dup2 volver (y cerrar el dup ped uno). Personalmente, no me gusta escribir implementaciones propias cat como se sugiere en otras respuestas. Si lo único que quieres es redirigir un solo comando shell con system a un archivo en el sistema de archivos, entonces probablemente la manera más directa y sencilla es construir el comando shell para hacer esto como

system("ls -l > Result"); 

Pero hay que tenga cuidado si el nombre del archivo (Resultado) proviene de la entrada del usuario ya que el usuario puede proporcionar algo como 'Result; rm -rf /*' como el nombre del archivo.

Además, en el tema de la seguridad, se debe considerar que especifica la ruta completa a ls como se sugiere en los comentarios:

system("/bin/ls -l > Result"); 
+1

Edité tu publicación para incluir una ruta de acceso absoluta a ls en tu ejemplo. – Wug

+0

Edición revertida porque el OP ejecuta '" ls "' y esto cambiaría el significado de la llamada al sistema. La pregunta tampoco está relacionada con rutas absolutas o relativas. Creo que es mejor preguntarle a @unkulunkulu si le gustaría revisar su respuesta. – Andomar

+0

@Andomar, en realidad, acepté la edición, pero de todos modos, ambos puntos son válidos, no veo la diferencia :) Wug, gracias por su sugerencia, se verá en los comentarios de todos modos. – unkulunkulu

2

Se debe utilizar la función de biblioteca popen() y leer fragmentos de datos desde el vuelto FILE * y escríbelos en el archivo de salida que quieras.

Reference.

4

La cosa más sencilla es utilizar > de hecho:

#include <stdio.h> 
int main() 
{ 
    system("ls -l > /some/file"); 

    return 0; 
} 

Una alternativa es usar popen(), algo a lo largo de las líneas de

#include <stdio.h> 
    #include <stdlib.h> 
    main() 
    { 
      char *cmd = "ls -l"; 
      char buf[BUFSIZ]; 
      FILE *ptr, *file; 

      file = fopen("/some/file", "w"); 
      if (!file) abort(); 
      if ((ptr = popen(cmd, "r")) != NULL) { 
        while (fgets(buf, BUFSIZ, ptr) != NULL) 
          fprintf(file, "%s", buf); 
        pclose(ptr); 
      } 
      fclose(file); 
      return 0; 
    } 
0

uso dup en lugar de dup2. dup crea un descriptor de archivo de alias, cuyo valor debe ser siempre el descriptor de archivo más pequeño disponible.

new_fd = dup(file); - En esta declaración file puede ser que tenga el valor 3 (porque es stdin0, stdout es 1 y stderr es 2).entonces new_fd será 4

Si desea redirigir stdout al archivo. Entonces haz lo siguiente.

close(stdout); 
new_fd = dup(file); 

Ahora DUP volverá 1 como el alias para el descriptor file, porque cerramos stdout descriptores de archivos abiertos por lo que son 0,2,3 y 1 es más pequeño descriptor de archivo disponible.

Si está utilizando dup2 medios, dup2(file,1); - hacer como esto

+0

El uso de 'dup()' en lugar de 'dup2()' es _only_ si no le importa dónde se coloca el duplicado. Si te importa, usa 'dup2()' - ¡ese es su propósito explícito! Si, en cambio, usted simplemente espera lo mejor, como lo hace esta respuesta, funcionará bien hasta que un día se rompa el patrón y no tenga idea de por qué falla. Esas son algunas de las sesiones de depuración que se pueden haber evitado simplemente haciéndolo de la manera correcta desde el principio. – mah

Cuestiones relacionadas