• # Fonction mini shell

    Posté par . En réponse au message Commande qui ne fonctionne pas. Évalué à 1. Dernière modification le 03 décembre 2015 à 23:31.

    J'ai finalement résolu mon problème pour le programme moncd précédent merci pour les explications, elles m'ont servi de bcp pour la compréhension.
    Par ailleurs, si j'ai un programme C qui a pour but d'exécuter le fonctionnement d'un mini shell comment pourrais je le modifier afin de rajouter la possibilité de lancer des processus en arrière-plan quand la ligne de commande se termine par un & ? L'indication est de ne pas faire le wait dans le parent.
    Le but c'est de pouvoir faire un mini shell complet à partir de celui ci voilà pourquoi j'avais besoin de créer un programme moncd pour simuler le fonctionnement de cd.

    Le programme est le suivant(il lit une ligne de commande, la découpe avec la fonction découper, fabrique un nouveau processus avec fork et tente d'y lancer la commande en allant chercher un fichier du même nom dans chacun des répertoires indiqué par PATH.):

     # include <stdio.h>
     # include <stdlib.h>
     # include <unistd.h>
     # include <sys/types.h>
     # include <sys/wait.h>
     # include <assert.h>
     # include <string.h>
     enum {
     MaxLigne = 1024, // longueur max d'une ligne de commandes
     MaxMot = MaxLigne / 2, // nbre max de mot dans la ligne
     MaxDirs = 100, // nbre max de repertoire dans PATH
     MaxPathLength = 512, // longueur max d'un nom de fichier
     };
     void decouper(char *, char *, char **, int);
     # define PROMPT "? "
     int main(int argc, char * argv[]){
     char ligne[MaxLigne];
     char pathname[MaxPathLength];
     char * mot[MaxMot];
     char * dirs[MaxDirs];
     int i, tmp;
     /* Decouper PATH en repertoires */
     decouper(getenv("PATH"), ":", dirs, MaxDirs);
     /* Lire et traiter chaque ligne de commande */
     for(printf(PROMPT); fgets(ligne, sizeof ligne, stdin) != 0; printf(PROMPT)){
     decouper(ligne, " \t\n", mot, MaxMot);
     for(i = 0; mot[i] != 0 ; i++) ;
     if (mot[0] == 0) // ligne vide
     continue;
     tmp = fork(); // lancer le processus enfant
     if (tmp < 0){
     perror("fork");
     continue;
     }
     if (tmp != 0){ // parent : attendre la fin de l'enfant
     while(wait(0) != tmp); 
     continue;
     }
     // enfant : exec du programme
     for(i = 0; dirs[i] != 0; i++){
     snprintf(pathname, sizeof pathname, "%s/%s", dirs[i], mot[0]);
     execv(pathname, mot);
     }
     // aucun exec n'a fonctionne
     fprintf(stderr, "%s: not found\n", mot[0]);
     exit(1);
     }
     printf("Bye\n");
     return 0;
     }
     /* decouper -- decouper une chaine en mots */
     void decouper(char * ligne, char * separ, char * mot[], int maxmot){
     int i;
     mot[0] = strtok(ligne, separ);
     for(i = 1; mot[i - 1] != 0; i++){
     if (i == maxmot){
     fprintf(stderr, "Erreur dans la fonction decouper: trop de mots\n");
     mot[i - 1] = 0;
     }
     mot[i] = strtok(NULL, separ);
     }
     }

    J'ai pensé à introduire au niveau du parent l'instruction:

    if(*mot[i-1] != '&')

    Mais l'exécution me produit une erreur.

    roger@roger-1005PX:~/Bureau$ gcc -g -Wall shell.c -o shell
    roger@roger-1005PX:~/Bureau$ ./shell 
    ? #notre mini shell
    ? echo essai #test avec echo
    ? essai
    ? sleep 10 & #test arrière plan
    sleep: intervalle de temps «&» incorrect.Saisissez « sleep --help » pour plus d'informations.

    Merci d'avance ...