2011-03-08 8 views

Respuesta

32

Uso system():

int status = system("./foo 1 2 3"); 

system() esperarán a foo para completar la ejecución, a continuación, devuelve una variable de estado que se puede utilizar para comprobar, por ejemplo, código de salida man 2 wait en su sistema Linux mostrará una lista de las diferentes macros que puede utilizar para examinar el estado, los más interesantes serían WIFEXITED y WEXITSTATUS

Alternativamente, si usted necesita leer la salida del foo a la salida estándar, utilice popen().

+1

sistema() se declara donde? –

+4

stdlib.h, encontrado en otra respuesta. –

+2

Ver https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=2130132 y una respuesta alternativa publicada por este autor. –

4

En C

#include <stdlib.h> 

system("./foo 1 2 3"); 

En C++

#include <cstdlib> 

std::system("./foo 1 2 3"); 

A continuación, abrir y leer el archivo como de costumbre.

1

¿Qué hay de la siguiente manera:

char* cmd = "./foo 1 2 3"; 
system(cmd); 
+4

Mientras que la asignación de una cadena literal a un '' char *, que está en desuso en C++ y una mala idea en C. –

+0

que quería decir: si bien es válida, no sólo "tiempo". :) –

1

Ésta es la manera de extender a args variable cuando usted no tiene los argumentos cifrados duros (aunque todavía se codifican técnicamente difícil en este ejemplo, pero debe ser fácil averiguar cómo extender ...):

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int argcount = 3; 
const char* args[] = {"1", "2", "3"}; 
const char* binary_name = "mybinaryname"; 
char myoutput_array[5000]; 

sprintf(myoutput_array, "%s", binary_name); 
for(int i = 0; i < argcount; ++i) 
{ 
    strcat(myoutput_array, " "); 
    strcat(myoutput_array, args[i]); 
} 
system(myoutput_array); 
15

puede utilizar fork() y system() para que su programa no tiene que esperar hasta system() devoluciones.

#include <stdio.h> 
#include <stdlib.h> 

int main(int argc,char* argv[]){ 

    int status; 

    // By calling fork(), a child process will be created as a exact duplicate of the calling process. 
    // Search for fork() (maybe "man fork" on Linux) for more information. 
    if(fork() == 0){ 
     // Child process will return 0 from fork() 
     printf("I'm the child process.\n"); 
     status = system("my_app"); 
     exit(0); 
    }else{ 
     // Parent process will return a non-zero value from fork() 
     printf("I'm the parent.\n"); 
    } 

    printf("This is my main program and it will continue running and doing anything i want to...\n"); 

    return 0; 
} 
+0

Sería mucho más eficiente simplemente usar execl o execv del proceso hijo porque no usará un shell, no va a bifurcar un nuevo hilo, y de todos modos está saliendo justo después de llamar al sistema. Además, el proceso se convertirá en zombie si no llamas a wait(). – Billy

27

La función system invoca un shell para ejecutar el comando. Si bien esto es conveniente, es bien conocido por security implications. Si puede especificar completamente la ruta del programa o script que desea ejecutar y puede permitirse perder la independencia de plataforma que proporciona system, puede usar un contenedor execve como se ilustra en la función exec_prog a continuación para ejecutar su programa de manera más segura. .

Así es como se especifica los argumentos de la persona que llama:

const char *my_argv[64] = {"/foo/bar/baz" , "-foo" , "-bar" , NULL}; 

Luego llama a la función exec_prog así:

int rc = exec_prog(my_argv); 

Aquí está la función exec_prog:

static int exec_prog(const char **argv) 
{ 
    pid_t my_pid; 
    int  status, timeout /* unused ifdef WAIT_FOR_COMPLETION */; 

    if (0 == (my_pid = fork())) { 
      if (-1 == execve(argv[0], (char **)argv , NULL)) { 
        perror("child process execve failed [%m]"); 
        return -1; 
      } 
    } 

#ifdef WAIT_FOR_COMPLETION 
    timeout = 1000; 

    while (0 == waitpid(my_pid , &status , WNOHANG)) { 
      if (--timeout < 0) { 
        perror("timeout"); 
        return -1; 
      } 
      sleep(1); 
    } 

    printf("%s WEXITSTATUS %d WIFEXITED %d [status %d]\n", 
      argv[0], WEXITSTATUS(status), WIFEXITED(status), status); 

    if (1 != WIFEXITED(status) || 0 != WEXITSTATUS(status)) { 
      perror("%s failed, halt system"); 
      return -1; 
    } 

#endif 
    return 0; 
} 

Recuerde la incluye:

#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <stdio.h> 

Ver related SE post para situaciones que requieren la comunicación con el programa ejecutado a través de descriptores de archivos tales como stdin y stdout.

+0

¿Entonces el código anterior no usa shell para ejecutar el comando? – user3769778

2
#include <unistd.h> 

int main() { 
    if (fork() == 0) { 
      execl("foo", "foo", "1", "2", "3", 0); 
      # We woundn't still be here if execl() was successful, so we exit with a non-zero value. 
      return -1; 
    } 

    return 0; 
} 
Cuestiones relacionadas