Newsgroup: it.comp.lang.c
Titolo: Shell linux

Altro esercizietto, una semplice shell linux che fa solo una cosa:
accetta 2 comandi e ridireziona l'output del primo come input del secondo.
Ho cercato di indentare un pochino meglio, c'� da dire che col copia e 
incolla qualcosa si incasina comunque.
 
 
 
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
int n,i;
char buff[80]; //stringa da imput
char prompt[10];
char * commands[3]; //array di puntatori alle stringhe di: comando 1, 
ridirezione e comando 2 estratti da buff
sprintf(prompt, "Prompt:> ");
write(1,prompt,10);
 
while((n=read(0,buff,80))!=0){
     buff[n-1]='\0';
 
     if ((strcmp(buff,"esci"))==0) {exit(0);}
     i=0;
     commands[i]=strtok(buff," ");
 
        while(commands[i]!=NULL){
        i++;
        commands[i]=strtok(NULL," ");
 
        }
 
     if (i!=3) {printf("Uso: comando1 | comando2\n"); exit(1);}
     if ((strcmp(commands[1],"|"))!=0) {
     printf("Uso: comando1 | comando2\n"); exit(1);
     }
 
     int pid;
     if ((pid=fork())==-1){ // prima fork
     perror("Errore\n"), exit(1);
     }
     if (pid==0){
     int fd[2];
     pipe(fd);
 
     if ((pid=fork())==-1) { // seconda fork
     perror("Errore\n"), exit(1);
     }
     if (pid==0){
     //comando1
     close(1);
     dup(fd[1]);
     close(fd[1]);
     close(fd[0]);
     execlp(commands[0],commands[0], (char *) 0);
     }
     else{ //comando2
     close(0);
     dup(fd[0]);
     close(fd[0]);
     close(fd[1]);
     execlp(commands[2],commands[2], (char *) 0);
     }
     }
     else
     pid=wait(NULL);
     write(1,prompt,10);
     lseek(0,0,SEEK_SET);
}
 
return 0;
}
 

 [...]
 
Non ho letto il codice a fondo, ma rinnovo il consiglio che ti ho dato prima: suddividi il codice in unità logiche (funzioni) che facciano una ben determinata operazione.
 
Questo non solo per evitare ripetizioni (nel tuo caso il codice per eseguire un processo esterno e per riportare un errore di comando invalido), ma anche per avere codice più leggibile dato che la funzione main si potrebbe ridurre a qualcosa del genere (pseudo codice):
 
int main() {
    init_shell();
 
    while ... {
        parse_command();
        if (<command="esci">) {
            ....
        }
        else ... {
            spawn_command(command1, ...);
            spawn_command(command2, ...);
            ...
        }
        else {
            invalid_command();
        }
    }
}
 
 
Ciao  Manlio

 Ciao  Manlio
 
 
 
 
Ovviamente creare funzioni per gestire macro compiti rende molto più 
leggibile e pulito il codice, oltre che più semplice da controllare.
Mi rendo conto che i miei esercizi, se tendono a superare le 10 righe di 
codice, diventano facilmente un mappazzone (cit.) :-P
 
In realtà faccio cosi' per far prima, sicuramente se dovessi lavorare 
seriamente ad un progetto farei come dici, ma al momento sto facendo 
solo pratica con le system call, e voglio impadronirmene quanto prima 
risparmiando il  più tempo possibile :-)
Ovviamente sarebbe meglio iniziare subito col le buone abitudini, ma il 
poco tempo per studiare mi frega.
 
Grazie per i preziosi consigli cmq, torneranno molto utili quando e se 
mi troverò a fare progetti più "seri".