2011-03-28 9 views
17

En Linux, me gustaría escribir un programa C que inicia otro programa. Cuando se ejecuta el programa, el intérprete de comandos estará esperando que ingrese un comando que haya definido en su programa. Este comando lanzará el segundo programa.¿Cómo se escribe un programa en C para ejecutar otro programa?

Por ejemplo, supongamos que hay un simple programa de C llamado "hola" en el mismo directorio que el programa de invocación. El programa "hola" imprime la salida "hola, mundo". El primer programa se ejecutaría y el usuario ingresaría el comando "hola". El programa "hola" se ejecutará y "hola, mundo". se enviaría a la shell.

He hecho algunas búsquedas, y la gente sugirió las funciones "fork()" y "exec()". Otros dijeron usar "sistema()". No tengo conocimiento sobre estas funciones. ¿Cómo llamo a estas funciones? ¿Son apropiados para usar?

El código de ejemplo con explicaciones sería de gran ayuda. Otras respuestas también son bienvenidas. Tu ayuda es muy apreciada.

Respuesta

25
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> /* for fork */ 
#include <sys/types.h> /* for pid_t */ 
#include <sys/wait.h> /* for wait */ 

int main() 
{ 
    /*Spawn a child to run the program.*/ 
    pid_t pid=fork(); 
    if (pid==0) { /* child process */ 
     static char *argv[]={"echo","Foo is my name.",NULL}; 
     execv("/bin/echo",argv); 
     exit(127); /* only if execv fails */ 
    } 
    else { /* pid!=0; parent process */ 
     waitpid(pid,0,0); /* wait for child to exit */ 
    } 
    return 0; 
} 
+2

+1 para una solución más flexible –

+0

¿Por qué 'echo' en la variable' argv' y en la llamada 'execv'? – User

+0

@User, porque es argv [0], es decir, * nombre del programa *. – 0andriy

3

¿No será suficiente para ti? system()?

/* ... */ 
if (!strcmp(cmd, "hello")) system("hello.exe"); 
/* ... */ 
+1

es Linux, por lo que es probable que no se encuentre ningún exe. Sin embargo, puede ser cualquier nombre. –

+1

El sistema es la función '', funcionaría en Unix. – vissi

+0

@Vladimir: el OP indica que el programa es "hello.c". Lo más probable es que no. Solo quería señalarlo en la dirección correcta cuando intenta mi fragmento :) – pmg

1

Para el caso más simple que debiera dos programas compilados en un directorio:

> ls 
. 
hello 
second 

En segundo programa sólo tiene que llamar system("hello");

+2

Las cosas no funcionan de esa manera en los entornos * nix. system (...) invoca un shell (/ bin/sh en realidad), que buscará en la búsqueda PATH para ejecutables (variable de entorno $ PATH). Como uno no debe colocar el directorio de trabajo (./) en PATH por razones de seguridad, colocar el programa de llamada en el mismo directorio que la persona que llama no funcionará. Esto es diferente de Windows, donde el directorio de trabajo está incluido en la búsqueda. – datenwolf

+0

Esto funcionó para mí (para llamar a un ejecutable). –

6

Si eres nuevo en el tenedor, la representación gráfica sobre fork y exec puede ser útil para usted.

Representación de fork()

+-------------+ 
    |main program | 
    +-------------+ (fork()) 
     |___________________________ 
    +-------------+     | 
    |main program |   +-------------+ 
    +-------------+   |main program | 
     |     +-------------+ 
    +-------------+     |  (exec()) 
    |main program |   +-------------+ 
    +-------------+   |hello program| 
          +-------------+ 

Como es posible que ya han leído en un tutorial, después de llamar fork() se crea una copia duplicada del programa existente, y la exec() después de que reemplaza esa copia con el nuevo programa, que le pasa como argumentos. Dos unidades de ejecución para dos programas se ejecutarán después de fork().

0

He hecho algunas búsquedas, y la gente sugirió las funciones fork() y exec(). Otros dijeron usar system(). No tengo conocimiento sobre estas funciones. ¿Cómo llamo a estas funciones? ¿Son apropiados para usar?

Sí. Lea primero la documentación (man página), p. de fork(2), exec(3), system(3). Es muy probable que tenga esa documentación localmente en su computadora, usando man(1). Observe que system utiliza sh (a través bash(1) o dash(1)), porque es fork -ing, execve(2) -ing y waitpid(2) -ing la cáscara /bin/sh POSIX.

Creo que fork es difícil de entender porque con éxito se devuelve "dos veces". No trataré de explicarlo aquí (necesitaré muchas páginas para eso). Recomiendo leer fork (system call) wikipage al principio. Luego, lea un buen libro de programación de Linux, e.g Advanced Linux Programming (descargable libremente).

Lea también sobre Virtual Address Space, y proc(5).

También puede leer Operating Systems: Three Easy Pieces para obtener una vista más general.

Cuestiones relacionadas