Página 1 de 1

Problemas con fork(), system(), etc.

NotaPublicado: 2017-05-03 10:47 @491
por Blue_Shell
Más que un mensaje donde pido ayuda esto es más algo como "¿cómo se haría esto?" y dudas sobre estos dos hermosos comandos: fork y system.

Me hallaba yo en mi intento de programación de mi propia shell basada en Perl (de lo que últimamente van exclusivamente mis problemas, nunca sospeché que algo me llevara a tantas dudas) cuando, después de hacer módulos con subrutinas y variables que se modificaban desde el script de inicio para que unos ciertos comandos por defecto funcionen a la perfección (en esta shell van precedidos de un "#", por ej.: #ls, #cd, #get (una utilidad parecida a wget), #chmod, #help, #reboot, etc.) me vino la duda existencial, la parte más imponente de todo el proyecto desde el principio: Los comandos por defecto están bien, pero, ¿y si quiero hacer "fstab", por ejemplo? Y me vino a la cabeza system() con sus variantes qx(), exec() y todo eso, pero estos comandos me generan unas dudas:

- ¿Son independientes de una shell? Si voy a hacer una shell que dependa de otra para funcionar, vaya. Con independientes me refiero a que si necesitan de algo que no sea el compilador de Perl para funcionar estos comandos, no sé si me he explicado.

Para que quede más claro pongo un ejemplo. Si yo hiciera:
Sintáxis: [ Descargar ] [ Ocultar ]
  1. ... 
  2. system("ls") ; 
  3. ... 

si el sistema no tuviera una shell que interpretara el comando, ¿funcionaría?

Luego de pensar usar este método, pensé: "No puede ser tan fácil, ¿el alojamiento de memoria?, ¿los PID?, así que buscando proyectos similares al mio encontré uno muy bueno que, aunque estaba en C, me sirvió mucho para comprender el trabajo de una shell mejor y me sirvió para algunas ideas, ya que C y Perl son parecidos, según mi opinión, y vi el uso extensivo del comando fork() que poseemos también en el amado Perl, así que asumí que algo tenía que ver con esto. Estudié un poco el uso de fork pero no me quedó claro.

Llegados a este punto y después de explicaros difusamente todas mis penas, ¿cómo podría hacer esto? ¿Cómo hacer que mi shell interprete comandos? ¿system o fork? No sé si pido mucho. De ser así notificádmelo para proseguir con mi búsqueda individual. Muchísimas gracias por adelantado y os deseo buena semana.

#DATOS:
página web del proyecto nombrado de la shell en C => https://brennan.io/2015/01/16/write-a-shell-in-c/

Re: Problemas con fork(), system(), etc.

NotaPublicado: 2017-05-03 11:58 @540
por explorer
No sé si viste mi último comentario del hilo anterior, sobre el proyecto Perl Power Tools, así que te lo enlazo de nuevo.

Sobre qx(), fork, system y exec, se trata de cosas distintas...

Te copio aquí algunas partes extraídas del perlfunc:

exec
La función exec ejecuta un comando del sistema y nunca regresa.
...
Si hay más de un argumento en LISTA, se llama a execvp(3) con los argumentos de LISTA. Si sólo hay un elemento en la LISTA, se comprueba si el argumento tiene metacaracteres shell, y si lo hay, el argumento entero es pasado al shell de comandos para que interpretarse (suele ser /bin/sh -c en plataformas Unix, pero varía en otras). Si no hay metacaracteres shell en el argumento, se divide en palabras y pasadas directamente a execvp, que es más eficiente.

system
Hace exactamente lo mismo que exec, excepto que se hace primero un fork y el proceso padre espera a que el proceso hijo termine. Tenga en cuenta que el tratamiento de los argumentos varía en función del número de argumentos.

fork
Hace una llamada del sistema fork(2) para crear un nuevo proceso ejecutando el mismo programa en el mismo punto. Devuelve el pid del hijo al proceso padre, 0 al proceso hijo, o undef si el fork no funcionó.

Más información en perlfork.

qx
Una cadena que es (posiblemente) interpolada y entonces ejecutada como un comando del sistema con /bin/sh o su equivalente. Los comodines del intérprete, tuberías y redirecciones serán respetados. Todo lo que salga por la salida estándar del comando se devuelve; la salida estándar de error no se verá afectada.

Entonces... cuando estás pidiendo que Perl ejecute un comando del sistema con system(), arrancará un proceso hijo con fork (para mantenerse lo más aislado posible) y lo ejecutará. Si el comando lleva metacaracteres, lo ejecutará pasándolo a un shell (arrancará un sh y le pasará el comando). qx() hará lo mismo, pero nos devolverá la salida estándar en lugar del resultado (estado) de la ejecución.

¿Son independientes de un shell? Solo si usas system/exec y sin usar metacaracteres. Y el comando debe existir en el sistema.

Si ejecutas en Perl system("ls"), le estamos pidiendo al sistema operativo que arranque el comando "ls". Si ese comando no está instalado, pues nos devolverá un error (comando no encontrado).

Ahora bien: ¿Qué hace un "ls"? Pues ir al directorio indicado, y mostrar cada uno de los archivos que hay dentro de él. Y eso... lo puedes hacer con las funciones opendir(), readdir() y closedir() del Perl, y entonces ya NO dependes de la existencia de un comando externo.