c++ - funcion - usando exec para ejecutar un comando del sistema en un nuevo proceso
proceso fork linux (3)
La familia de funciones Exec
reemplaza el proceso actual con el nuevo ejecutable.
Para hacer lo que necesita, use una de las funciones fork()
y haga que el proceso secundario exec
la nueva imagen.
[respuesta a la actualización]
Está haciendo exactamente lo que le dijo: no tiene que presionar "enter" para finalizar el programa: ya ha salido. El shell ya ha dado un aviso:
[wally@zenetfedora ~]$ ./z
before
22397
done
[wally@zenetfedora ~]$ 0 << here is the prompt (as well as the pid)
total 5102364
drwxr-xr-x. 2 wally wally 4096 2011-01-31 16:22 Templates
...
La salida de ls
tarda un rato por lo que entierra el aviso. Si desea que la salida aparezca en un orden más lógico, agregue sleep(1)
(o tal vez más) antes del "hecho".
Intento generar un proceso que ejecuta un comando del sistema, mientras que mi propio programa continúa y dos procesos se ejecutarán en paralelo. Estoy trabajando en Linux.
Busqué en línea y parece que debería usar la familia exec (). Pero no funciona tan bien como esperaba. Por ejemplo, en el siguiente código, solo veo impreso "antes", pero no "hecho".
Tengo curiosidad si estoy emitiendo algo?
#include <unistd.h>
#include <iostream>
using namespace std;
main()
{
cout << "before" << endl;
execl("/bin/ls", "/bin/ls", "-r", "-t", "-l", (char *) 0);
cout << "done" << endl;
}
[ACTUALIZAR]
Gracias por tus comentarios. Ahora mi programa se ve así. Todo funciona bien, excepto al final, tengo que presionar enter para terminar el programa. No estoy seguro de por qué tengo que presionar la última entrada?
#include <unistd.h>
#include <iostream>
using namespace std;
main()
{
cout << "before" << endl;
int pid = fork();
cout << pid << endl;
if (pid==0) {
execl("/bin/ls", "ls", "-r", "-t", "-l", (char *) 0);
}
cout << "done" << endl;
}
Te estás perdiendo la parte donde execl () reemplaza tu programa actual en la memoria con /bin/ls
Sugeriría mirar popen()
que bifurcará y ejecutará un nuevo proceso, luego le permitirá leer o escribir a través de un conducto. (O si necesita leer y escribir, fork()
usted mismo, luego exec()
)
Te estás perdiendo una llamada al fork
. All exec
does es reemplazar la imagen del proceso actual con la del nuevo programa. Usa el fork
para generar una copia de tu proceso actual. Su valor de retorno le dirá si es el hijo o el padre original el que se está ejecutando. Si es el niño, llame al exec
.
Una vez que haya realizado ese cambio, solo parece que necesita presionar Enter para que los programas finalicen. Lo que está sucediendo realmente es esto: el proceso principal bifurca y ejecuta el proceso hijo. Ambos procesos se ejecutan, y ambos procesos imprimen a stdout al mismo tiempo. Su salida está distorsionada. El proceso principal tiene menos que hacer que el hijo, por lo que termina primero. Cuando termina, su caparazón, que estaba esperando, se despierta e imprime el aviso habitual. Mientras tanto, el proceso hijo aún se está ejecutando. Imprime más entradas de archivo. Finalmente, termina. El shell no está prestando atención al proceso hijo (su nieto), por lo que el shell no tiene ninguna razón para volver a imprimir el mensaje. Mire con más cuidado el resultado que obtiene, y debería poder encontrar su prompt de comando habitual enterrado en la salida de ls
arriba.
El cursor parece estar esperando que presiones una tecla. Cuando lo haces, el shell imprime un mensaje, y todo se ve normal. Pero en lo que respecta al caparazón, todo ya era normal. Podrías haber escrito otro comando antes. Hubiera parecido un poco extraño, pero el intérprete de comandos lo habría ejecutado normalmente porque solo recibe datos del teclado, no del proceso secundario, imprimiendo caracteres adicionales en la pantalla.
Si usa un programa como la top
en una ventana de consola separada, puede ver y confirmar que ambos programas ya se hayan ejecutado antes de tener que presionar Entrar.