ESECUTORE DI COMANDI

di Anonimizzato15213 il
10 risposte
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

  • Potresti migliorare la leggibilità usando i tag code, per esempio
  • Potresti fare un esempio ?
    grazie!
  • Come per l'altro thread ... tasto Code ... non c'è esempio ...
  • 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 */
              }
         }
    
    }
    
  • Cosa vuoi migliorare? La leggibilità del codice, l'efficienza, l'utilizzo di risorse, la velocità di esecuzione?
  • Vorrei cercare di scrivere nel file out.1, out.2 ... quello che viene stampato a video dopo l'esecuzione del comando.
  • E il codice che hai postato non lo fa? Che errore ti dà?
  • 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  */
              }
                   
         }
    }
    
  • Di nuovo deduco che il codice non lo hai scritto tu, giusto?
  • Certo che l'ho scritto io!
    perchè ?
Devi accedere o registrarti per scrivere nel forum
10 risposte