gpt4 book ai didi

c - C 语言 shell 、输入和管道

转载 作者:行者123 更新时间:2023-11-30 16:47:55 25 4
gpt4 key购买 nike

我一直在用 C 语言制作一个迷你 shell,它必须接收至少有 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 正在尝试从中读取。

关于c - C 语言 shell 、输入和管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43170461/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com