ESECUTORE DI COMANDI

di il
10 risposte

ESECUTORE DI COMANDI

Scrivere un programma che continuamente legge dallo standard input righe di testo terminate da caratteri di fine riga (\n). Il programma termina quando inserisco una riga di testo vuota. Ciascuna riga rappresenta un comando esterno da eseguire, quindi contiene il nome del comando e gli eventuali argomenti:
comando argomento1 argomento2 ...
Il programma deve eseguire sequenzialmente i comandi (lanciati con gli eventuali argomenti indicati) in modo da salvare lo standard output di ciascun comando su di un file chiamato "out.k", ove k è il numero progressivo del comando eseguito.
Ad esempio, se il programma inizialmente legge dallo standard input le seguenti tre righe:
ls -la
date
cat /etc/passwd
allora il file "out.1" conterrà l’elenco dei file della directory, il file "out.2" conterrà la data e l’ora al momento dell’esecuzione, ed il file "out.3" sarà una copia del file “/etc/passwd”.
Risolvere inoltre lo stesso esercizio supponendo però di voler eseguire i comandi non sequenzialmente ma in parallelo, ovvero generando n processi in parallelo (dove n è il numero complessivo di righe di comando inserite) ognuno dei quali dedicato alla esecuzione di una riga di comando. Il file "out.k" conterrà quindi lo standard output del comando eseguito per k-mo (l'ordine di esecuzione dipenderà dallo scheduler).
Si gestiscano anche le situazioni di errore che si possono verificare più frequentemente.

#include <stdio.h>
#include <sys/types.h>

void analizza(char *line, char **argv)
{
while (*line != '\0') { /* se la stringa presa in considerazione non rappresenta la fine della riga */
while (*line == ' ' || *line == '\n'){
*line = '\0'; /* replace white spaces with 0 */
line++;
}

*argv = line; /* save the argument position forse è *argv=*line; */
argv++;
while (*line != '\0' && *line != ' ' && *line != '\n')
line++; /* skip the argument until ... */
}

*argv = '\0'; /* mark the end of argument list */
}

void execute(char *argv) {
pid_t pid;
int stato;

if ((pid = fork()) < 0) {
printf("*** ERRORE: creazione processo figlio fallita\n");
exit(1);
}
else if (pid == 0) { /* processo figlio */
if (execvp(*argv, argv) < 0) { /* esegue il comando */
printf("*** ERRORE: esecuzione fallita\n");
exit(1);
}
}
else { /* processo padre */
while (wait(&stato) != pid) {
/* aspetta il completamento del processo figlio */
}

}
}

void main(void) {

char line[1024]; /* input */
char *argv[64]; /* gli argomenti presenti nella linea di comando */
int continua=1;
while (continua) {

printf("Inserisci il comando da eseguire: ");
gets(line); /* leggi la linea di comando */
printf("\n");
analizza(line, argv); /* analizza line */
if (strcmp(argv[0], "exit") == 0) /* è una "exit"? */
exit(0); /* esegui exit */
else {
if(strcmp(argv[0], "\0")
continua=0; // oppure exit(0);
else
execute(argv); /* otherwise, execute the command */
}
}

}

come posso migliorarlo?
grazie a tutti!

10 Risposte

  • Re: ESECUTORE DI COMANDI

    Potresti migliorare la leggibilità usando i tag code, per esempio
  • Re: ESECUTORE DI COMANDI

    Potresti fare un esempio ?
    grazie!
  • Re: ESECUTORE DI COMANDI

    Come per l'altro thread ... tasto Code ... non c'è esempio ...
  • Re: ESECUTORE DI COMANDI

    Scusa non avevo capito !
    
    
    #include  <stdio.h>
    #include  <sys/types.h>
    
    void  analizza(char *line, char **argv)
    {
         while (*line != '\0') {       /* se la stringa presa in considerazione non rappresenta la fine della riga */ 
              while (*line == ' ' || *line == '\n'){
                   *line = '\0';     /* replace white spaces with 0    */
                   line++;
              }
    
              *argv = line;          /* save the argument position  forse è *argv=*line;   */
              argv++;
              while (*line != '\0' && *line != ' ' && *line != '\n') 
                   line++;             /* skip the argument until ...    */
         }
    
         *argv = '\0';                 /* mark the end of argument list  */
    }
    
    void  execute(char *argv) {
         pid_t pid;
         int stato,indice=1;
         FILE *stream, *fopen();
    
         if ((pid = fork()) < 0) {     
              printf("*** ERRORE: creazione processo figlio fallita\n");
              exit(1);
         }
         else if (pid == 0) {          /* processo figlio */
              if (execvp(*argv, argv) < 0) {     /* esegue il comando */
                   printf("*** ERRORE: esecuzione fallita\n");
                   exit(1);
              }
         }
         else {   
    	 stream = fopen("out.%d", indice,"r,w")  ; // apro il file in letture e scrittura
    	 indice++; 
    	 *stream = stdout; // fprint( *stream, stdout) 
    	                             /* processo padre */
              while (wait(&stato) != pid) {    
                    /* aspetta il completamento del processo figlio  */
              }
                   
         }
    }
    
    void  main(void) {
         
         char  line[1024];             /* input */
         char  *argv[64];              /* gli argomenti presenti nella linea di comando */
         int continua=1;
         while (continua) {                   
              
              printf("Inserisci il comando da eseguire: ");     
              gets(line);              /*  leggi la linea di comando  */
              printf("\n");
              analizza(line, argv);       /*   analizza line               */
              if (strcmp(argv[0], "exit") == 0)  /* è una "exit"?     */
                   exit(0);            /*  esegui exit  */
              else {
                    if(strcmp(argv[0], "\0")
                               continua=0; // oppure exit(0);
                    else
                        execute(argv);           /* otherwise, execute the command */
              }
         }
    
    }
    
  • Re: ESECUTORE DI COMANDI

    Cosa vuoi migliorare? La leggibilità del codice, l'efficienza, l'utilizzo di risorse, la velocità di esecuzione?
  • Re: ESECUTORE DI COMANDI

    Vorrei cercare di scrivere nel file out.1, out.2 ... quello che viene stampato a video dopo l'esecuzione del comando.
  • Re: ESECUTORE DI COMANDI

    E il codice che hai postato non lo fa? Che errore ti dà?
  • Re: ESECUTORE DI COMANDI

    No, non mette lo standard out nel file! perchè non so se si fa così:
    
    void  execute(char *argv) {
         pid_t pid;
         int stato,indice=1;
         FILE *stream, *fopen();
    
         if ((pid = fork()) < 0) {     
              printf("*** ERRORE: creazione processo figlio fallita\n");
              exit(1);
         }
         else if (pid == 0) {          /* processo figlio */
              if (execvp(*argv, argv) < 0) {     /* esegue il comando */
                   printf("*** ERRORE: esecuzione fallita\n");
                   exit(1);
              }
         }
         else {   // si fa cosi ?????????????
    	 stream = fopen("out.%d", indice,"r,w")  ; // apro il file in letture e scrittura
    	 if(!stream){
    	 	 printf(“Errore in apertura file input\n”);
    		return
    	 }
    	 indice++; 
    	 *stream = stdout; // fprint( *stream, stdout) 
    	                             /* processo padre */
              while (wait(&stato) != pid) {    
                    /* aspetta il completamento del processo figlio  */
              }
                   
         }
    }
    
  • Re: ESECUTORE DI COMANDI

    Di nuovo deduco che il codice non lo hai scritto tu, giusto?
  • Re: ESECUTORE DI COMANDI

    Certo che l'ho scritto io!
    perchè ?
Devi accedere o registrarti per scrivere nel forum
10 risposte