[英]shell in C, input & pipes
我一直在用C制作一个迷你外壳,该外壳必须接收带有至少3个参数的命令,然后解析它们,然后应用fork()和exec(),如果您只按Enter,它应该再次打印提示。 它还必须接受多个管道,这就是我被卡住的地方。 这是我的代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int main(){
char command[50];
char* token;
char* param[50][50];
int i,j,k;
while(1){
printf("shell:~");
fgets(command, sizeof(command), stdin);
i=0,j=0;
token = strtok(command," \n\0\t");
while(1){
if(token==NULL) break;
else if(strcmp(token,"|")==0){
param[i][j]=0;
i = i+1;
j=0;
token = strtok(NULL," \n\0\t");
}
else{
param[i][j]=token;
token = strtok(NULL," \n\0\t");
j = j+1;
}
}
param[i][j]=0;
直到这里,每个人都能正常工作。
pid_t pid1,pid2;
int fd1[2],fd2[2];
//int numpipe = i-1;
pipe(fd1);
pipe(fd2);
int status;
pid1 = fork();
if(pid1==0){
k=0;
while(k<i+1){
pid2 = fork();
if(pid2==0){
if(k==0){// if it is first
if(k==i){//and last one
execvp(param[k][0],param[k]);
}else{
dup2(fd1[1],STDOUT_FILENO);
close(fd1[0]);
execvp(param[k][0],param[k]);
}
}else if(0<k<i){//if it is in the middle
if(k%2==0){ // position odd
dup2(fd2[0],STDIN_FILENO);
close(fd2[1]);
dup2(fd1[1],STDOUT_FILENO);
close(fd1[0]);
execvp(param[k][0],param[k]);
}else{ //position
dup2(fd1[0],STDIN_FILENO);
close(fd1[1]);
dup2(fd2[1],STDOUT_FILENO);
close(fd2[0]);
execvp(param[k][0],param[k]);
}
}else{//if it is lasts
if(k%2==0){
dup2(fd2[0],STDIN_FILENO);
close(fd2[1]);
execvp(param[k][0],param[k]);
}else{
dup2(fd1[1],STDIN_FILENO);
close(fd1[1]);
execvp(param[k][0],param[k]);
}
}
}else{
k++;
wait(NULL);
}
}
}
else{
wait(NULL);
}
}
return 0;
}
如果我仅使用1条命令,则代码效果很好,但是当我放置管道时,它无法获得输入,例如:
shell:~ls -l
total 112
-rw-r--r-- 1 cristian cristian 72018 mar 28 13:25 (107315)proyecto1-SO2017-1.pdf
-rw-rw-r-- 1 cristian cristian 0 abr 2 12:23 a.out
-rw-rw-r-- 1 cristian cristian 1082 abr 1 23:47 reaspaldo2
-rw-rw-r-- 1 cristian cristian 1217 abr 2 03:00 reaspaldo2.c
-rw-rw-r-- 1 cristian cristian 962 abr 1 19:40 respaldo1
-rw-rw-r-- 1 cristian cristian 636 abr 2 01:10 respaldo1.c
-rwxrwxr-x 1 cristian cristian 13200 abr 2 12:35 shell
-rw-r--r-- 1 cristian cristian 1984 abr 2 12:36 shell.c
-rw-r--r-- 1 cristian cristian 807 mar 29 11:41 shell.c~
shell:~ls -l | wc
wc: 'standard input': Bad file descriptor
0 0 0
shell:~
它与STDIN_FILE有关,但是我也不能很好地实现管道和fork。
将您的问题减少到最小的可重现情况:
#include <unistd.h>
#include <stdio.h>
int main(void)
{
char *argv[] = {"wc", NULL};
int fd1[2];
pipe(fd1);
dup2(fd1[1],STDIN_FILENO); /* Wrong end of the pipe !! */
close(fd1[1]);
execvp(argv[0], argv);
perror(argv[0]);
return 1;
}
问题是fd1[1]
是管道的写端,但是wc
试图从中读取。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.