gpt4 book ai didi

c - 在 c 中创建的 minishell 无法按预期工作,与管道相关

转载 作者:太空宇宙 更新时间:2023-11-04 04:24:29 25 4
gpt4 key购买 nike

我在我的操作系统签名中用 c 语言制作了一个 UNIX minishell。我只需要改进 shell 本身,我们有一个用于实现 yacc 的预制解析器和一个用于在其他文件中实现 lex 的扫描器。要修改的文件是主执行文件msh.c。

好吧,当我尝试实现管道序列时,问题就开始了。这是我做的:

int executePipeLine (char*** argvv, int bg, char** filev, int n){
int i;
int in = 0;
pid_t pid;
int fd[2];

for (i = 0 ; i < n-1 ; i++){

pipe(fd);
pid_t pid = fork();


if (pid == 0){ //child

if (in != STDIN_FILENO){
dup2(in, STDIN_FILENO);
close(in);

}

if (fd[1] != STDOUT_FILENO){
dup2(fd[1], STDOUT_FILENO);
close(fd[1]);
}

execvp(argvv[i][0], argvv[0]);
}

else { //parent

close(fd[1]);
in = fd[0];
}


}

if(in != STDIN_FILENO){
dup2(in, STDIN_FILENO);
close(in);
}

pid_t lastpid = fork();
if(lastpid == 0){ //child

execvp(argvv[i][0], argvv[0]);


}

if(lastpid == -1){

perror("no se pudo crear el hijo\n");
exit(-1);

}
else { //parent

/* not bg*/
if(!bg ) {
int status;
while (wait(&status) != lastpid); /* wait the child. */
}

else {
/*bg mode*/
printf("pid del proceso last: %d\n", lastpid);

}

return 0;
}

}//end executePipeLine

这似乎工作正常。在 main 中,我们有一个名为 obtain_order() 的外部函数;返回命令数 + 1 并将其保存到 ret。如果 ret 为 1,我们继续提示,如果为 0,则表示 EOF(Control + D 键绑定(bind))结束 shell,如果为 >1,则执行命令。

给你:

int main(void)
{
char ***argvv;
int command_counter;
int num_commands;
int args_counter;
char *filev[3];
int bg;
int ret;
int reset = 0;
setbuf(stdout, NULL); /* Unbuffered */
setbuf(stdin, NULL);

while (1)
{
fprintf(stderr, "%s", "msh> "); /* Prompt */

ret = obtain_order(&argvv, filev, &bg);

printf("ret: %d\n", ret);
if (ret == 0) break; /* EOF */
if (ret == -1) continue; /* Syntax error */
num_commands = ret - 1; /* Line */
if (num_commands == 0) continue; /* Empty line */

if(num_commands > 1){

executePipeLine(argvv, bg, filev, num_commands);

}
else if (num_commands == 1){
executeCommand(argvv, bg, filev);

}

} //fin while

return 0;

} //end main

通过一个简单的命令一切正常。问题是当我尝试执行管道时。它显示了一个很好的结果,但我不知道我们,在下一次迭代中 ret 总是为 0,所以每次我尝试执行管道时,它都有效但关闭 shell 进程,并且必须再次执行它而不是继续提示。

你知道这里的问题是什么吗?

我希望你能理解我,我的英语并不完美。谢谢

最佳答案

在父进程(即您的迷你 shell)中,您正在dup标准输入:

...
else { //parent
close(fd[1]);
in = fd[0];
}

...

if(in != STDIN_FILENO){
dup2(in, STDIN_FILENO);
close(in);
}

当你的管道终止时, children 死了,管道不再可读=> stdin 被认为是关闭的。当您稍后在主循环中调用 obtain_order 时,它返回 0 (EOF) 并且您的程序退出。

关于c - 在 c 中创建的 minishell 无法按预期工作,与管道相关,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43081712/

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