Aménager un shell pour gérer les redirections > et 2>

Aménager un shell pour gérer les redirections > et 2> - C - Programmation

Marsh Posté le 19-05-2009 à 22:22:00    

bonjour je souhaiteais ajouter au shell script les redirections > et 2>
l une sur fichier.txt et l autre sur fichiererreur.txt
merci  
voici le code
 
/* code du shell ish */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <sys/wait.h>
 
#include "outils.h"
 
#define LBUF 500
char buf[LBUF], *reprise, *comm, *suite;
 
void lecture_commande(char * b, int L)
{
 /* envoie du prompt */
 setMessDelim('\n');
 while (1) {
   printf("OK >" );
   fflush(stdout);
   if (getMess(0,b,L) == 1) {
     /* suppression du \n de fin de saisie */
     b[strlen(b)-1] = '\0';
     if (strlen(b) == 0) continue;
     reprise = buf;
     return;
   }
   fprintf(stderr,"Erreur de saisie !!\n" );
 }
 
}
 
char * decoupe(void)
{
char * t, *ret;
    if (reprise == NULL) return(NULL);
    ret = t = reprise;
    while (1) {
        switch(*t) {
 case '\0' :
     reprise=NULL;
            return(ret);
     break;
 case '&' :
     if (*(t-1)== '<') break;
     if (*(t-1)== '>') break;
 case ';' :
            *t='\0';
     reprise=t+1;
            return(ret);
     break;
 }
        t++;
    }
}
 
char Delims[] = { " \t\n" };
 
int isDelim(char c)
{
int i;
 for(i=0;i<strlen(Delims);i++)
     if(c==Delims[i]) return(1);
 return(0);
}
 
int isNotDelim(char c)
{
int i;
        if(c=='\0') return(0);
 for(i=0;i<strlen(Delims);i++)
     if(c==Delims[i]) return(0);
 return(1);
}
 
void analyse(char * buf) /* trouve la commande */
{
char * t, vide='\0';
        t = buf;
        comm = suite = &vide;
        if (strlen(buf) == 0) return;
 /* je cherche le debut du 1er mot */
 while(isDelim(*t)) t++;
        if (*t=='\0') return;
 comm=t;
 while(isNotDelim(*t)) t++;
        if (*t=='\0') return;
        *t++='\0'; /* equivaut a : *t='\0'; t++; */
 /* je cherche le debut du 2em mot */
 while(isDelim(*t)) t++;
        if (*t=='\0') return;
 suite=t;
#ifdef TRACE
 printf("La commande est <%s> lasuite est <%s>\n",comm,suite);
#endif
}
 
int interne(void) /* verifie si comm est interne et l'execute */
{
char *rep;
uid_t uid;
struct passwd *P;
    if (strcmp("pwd",comm) == 0) {
 rep = getcwd(NULL,0);
 printf("%s\n",rep);
 free((void*)rep);
        return (1);
    }
    if (strcmp("cd",comm) == 0) {
#ifdef TRACE
 printf("cd : " );
#endif
 if (strlen(suite) == 0) {
            if ( (rep=getenv("HOME" )) == NULL) {
  /* consultation du fichie /etc/passwd */
  uid = getuid();
  while (1) {
      P = getpwent();
      if (P->pw_uid == uid) break;
  }
  endpwent();
  rep = P->pw_dir;
#ifdef TRACE
 printf("/etc/passwd -> uid = %d rep = %s\n", (int)uid, rep );
#endif
 
            }
#ifdef TRACE
           else
 printf("HOME = %s\n", rep );
#endif
        } else {
           rep = suite;
#ifdef TRACE
 printf("param = %s\n", rep );
#endif
        }
 if (chdir(rep) == -1) perror(rep);
        return (1);
    }
    if (strcmp("q",comm) == 0) {
 printf("Au revoir !\n" );
 exit(0);
        return (1);
    }
    if (strcmp("h",comm) == 0) {
 printf("Liste des commandes internes :\n" );
 printf("cd\t\t: changement du repertoire de travail\n\tsi aucun parametre on utilise le contenu de la variable HOME,\n\tsinon le repertoire specifie dans /etc/passwd.\n" );
 printf("h\t\t: ce present help\n" );
 printf("q\t\t: fin du shell\n" );
        return (1);
    }
    return (0);
}
 
void externe(void)
{
pid_t pid;
int n, i;
char *s;
char **P;
#ifdef TRACE
 printf("%s est une commande externe\n",comm);
#endif
    /* creation du fils qui doit executer la commande */
    if ((pid=fork()) == -1) perror(comm);
    else { /* code du pere ET du fils */
        if (pid == 0) { /* fils */
            /* parcours de suite en comptant le nb de mots */
            n=2; /* n = nb de mots dans suite + 2 */
            s = suite;
            while (*s != '0') {
               while (isDelim(*s)) s++;
               if (*s == '\0') break;
               n++;
               while (isNotDelim(*s)) s++;
            }
            /* fabrication du tableau */
            if ((P = (char **) malloc(sizeof(char*)*n)) == NULL)
  finerr("malloc" );
            P[0] = comm;
            i=1;
            s = suite;
            while (*s != '0') {
               while (isDelim(*s)) s++;
               if (*s == '\0') break;
               P[i++] = s;
               while (isNotDelim(*s)) s++;
               if (*s != '\0') *s++='\0';  
            }
            P[i] = NULL;
#ifdef TRACE
 printf("Fils : P = " );
        for (i=0; i<n; i++) printf("<%s> ", P[i]);
        printf("\n" );
#endif
        execvp(comm,P);
        fprintf(stderr,"La commande %s a echouee !\n",comm);
        exit(1);
        } else {
           waitpid(pid, &i,0);
        }
    }
}
 
int main(int N, char * P[])
{
char * dec;
/* initialisations */
 
/* lecture et execution des commandes */
    while(1) {
        /* lecture de la commande */
        lecture_commande(buf,LBUF);
#ifdef TRACE
 printf("commande : <%s>\n",buf);
#endif
 while ((dec=decoupe())!= NULL) {
    analyse(dec);
    if (! interne()) externe();
        }
 
 
 
 
    }
 
}
 
 

Reply

Marsh Posté le 19-05-2009 à 22:22:00   

Reply

Marsh Posté le 19-05-2009 à 22:31:28    

cool bonne idée :o
 
>.> c'est quoi le pb sinon :o

Reply

Marsh Posté le 19-05-2009 à 23:26:11    

Ba l idée c'est que j ai trouvé pas mal de doc  
mais je ne sais pas comment ni ou l intégrer dans le programme
j aurais bien voulus d'un coup de pouce
merci

Reply

Marsh Posté le 20-05-2009 à 08:10:39    

Intégrer quoi au juste ? La redirection ? Dans ce sens-là c'est juste une histoire de fprintf().

Reply

Marsh Posté le 20-05-2009 à 10:18:04    

je dois intégrer des redirection  
en sortie et en sortie erreur > 2>
je ne sais pas a quel niveau du code je dois l intégrer ni les commande exact je suis nul en programmation  
donc si quelqu'un pourrais m aider ce serais très très sympa
moi je suis plutôt réseau  routage etc...
je suis complètement perdu quand j ai du code en face de moi

Reply

Marsh Posté le 20-05-2009 à 10:38:44    

La redirection > redirige la sortie standard (stdout) dans un fichier.
La redirection 2> redirige la sortie erreur standard (stderr) dans un fichier.
 
Donc : fopen + remplacement des printf/fprintf(stderr dans le fichier ouvert.

Reply

Marsh Posté le 25-05-2009 à 15:24:35    

Si tu nous expliquait un peu ce que tu cherches à faire ?

Reply

Marsh Posté le 11-06-2009 à 14:00:58    

Il y a aussi la fonction freopen qui permet de faire des redirections.

Reply

Marsh Posté le 11-06-2009 à 14:28:24    

Il faut que tu joues tout ça à coup de open/dup2 avant d'exec.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed