c ++ commandes en pipeline avec execv et redirection des entrées

Essayer d’écrire un shell qui traite les commandes internes et externes. Je peux obtenir les commandes internes et une externe à la fois.

Ma question est de savoir comment obtenir une commande comme celle-ci à exécuter: “ls -l | grep lib | wc -l”

J’utilise un fork () et passe des commandes externes à travers execv () dans un char * [].

Des idées sur la façon de travailler cela? J’assume en utilisant pipe () ou quelque chose, mais je ne suis pas sûr.

Deuxième partie de la question: que diriez-vous de la redirection des entrées / sorties? Quelqu’un peut-il m’indiquer quelque part utile?

EDIT Jusqu’ici, @Alex W est mon héros. Cependant, comme je suis nouveau dans les commandes pipe () et dup2 (), j’est un peu hésitant sur l’utilisation de chaque appel et variable.

Voici le code que j’ai qui gère une seule commande externe (Example = “ls -l -a”):

pid_t pid; pid = fork(); if (pid < 0) { cout << "Fork failed." << endl; } else if (pid == 0) { execvp(exec_args[0], exec_args); //exec_args is a char*[] where _exit (EXIT_FAILURE); //exec_args[0] contains "/bin/ls" } //[1]="ls" and [2]="-l" [3]="-a" else { int status; waitpid(pid, &status, 0); } break; 

Vous utilisez pipe et dans les systèmes POSIX, une pipe fonctionne de la même manière qu’un fichier. Vous pouvez écrire sur un tuyau et lire à partir d’un tuyau, mais s’il n’y a rien dans le tuyau, il se bloque. Le meilleur endroit pour trouver des informations sur les appels système Unix est la page de manuel relative à l’appel système. Sur un système Unix, vous devez taper man pipe dans un terminal. Si vous n’avez pas access à un terminal Unix, recherchez simplement “man pipe” sur Google. L’avantage des pages de manuel est qu’elles vous indiquent les bibliothèques à inclure pour l’appel système donné. Assurez-vous de ne pas oublier que, lorsque vous utilisez un appel système de type exec , vous chargez un processus totalement nouveau dans cette mémoire et que le processus que vous exécutiez s’arrête complètement.

Pour l’utiliser, faites quelque chose comme ça:

 int main() { int id[2]; int fd[2]; int fd2[2]; int fd3[2]; FILE file; int status; int sz = 0; char buff[1000]; char buff2[1000]; ssortingng launch[2]; FILE *fp; launch[0] = "./anotherProgramToExecute"; launch[1] = "./yetAnotherProgram"; pipe(fd); pipe(fd2); pipe(fd3); for(int i = 0; i < 2; i++) { id[i] = fork(); if (id[i] == -1) /* an error occurred */ { perror("Fork failed.\n"); } else if (id[i] == 0) /* this is the child process currently acting */ { if(i == 0) { dup2(fd[1],1); } else if(i == 1) { dup2(fd2[0],0); dup2(fd3[1],1); } execlp(launch[i],launch[i], NULL); } else /* this is the parent process currently acting */ { sz = read(fd[0], buff, 1000); buff[sz] = '\0'; printf("buff = %s\n",buff); close(fd[0]); write(fd2[1],buff, 1000); read(fd3[0],buff2,1000); fp = fopen("bin.txt","w"); if(fp == NULL) printf("Cannot open file.\n"); else { fprintf(fp,buff2); fclose(fp); } //printf("Creation of Child Process #%d succeeded!\n",id[i]); while(waitpid(id[i], &status, WNOHANG) == 0) sleep(0.3); if (WIFEXITED(status)) { // successfully terminated children } else { perror("Child has not terminated correctly.\n"); } } } } 

Le meilleur tutoriel en ligne que j’ai vu concernant les pipes et autres est un vieux mais un bonus: http://beej.us/guide/bgipc/ . Vous pourriez le parcourir. On soupçonne que ça vous plaira.