【发布时间】:2021-01-31 17:29:42
【问题描述】:
我现在一直在做这个学校作业,而且我非常接近完成。
任务是用 C 创建一个 bash shell,这听起来很基本,但它必须支持管道、IO 重定向和管道命令中的标志。除了一件事,我一切都在工作;的|管道子进程没有得到用户命令进程子进程写入管道的任何数据。如果我要删除 pipechild 的子分支,并让 if(pipe_cmd[0] != '\0') 中的所有内容作为父级运行,它会工作得很好(减去因为 execlp 而结束程序)。如果我要在管道部分中使用 printf(),输出将在正确的文件或终端中,这只会导致来自用户命令进程子进程的输入无法到达它需要的位置。
有人看到我如何使用管道的问题吗?考虑到管道的定义,这一切对我来说都是 100% 正常的。
int a[2];
pipe(a);
//assume file_name is something like file.txt
strcat(file_name, "file.txt");
strcat(pipe_cmd, "wc");
if(!fork())
{
if(pipe_cmd[0] != '\0') // if there's a pipe
{
close(1); //close normal stdout
dup(a[1]); // making stdout same as a[1]
close(a[0]); // closing other end of pipe
execlp("ls","ls",NULL);
}
else if(file_name[0] != '\0') // if just a bare command with a file redirect
{
int rootcmd_file = open(file_name, O_APPEND|O_WRONLY|O_CREAT, 0644);
dup2(rootcmd_file, STDOUT_FILENO);
execlp("ls","ls",NULL); // writes ls to the filename
}
// if no pipe or file name write...
else if(rootcmd_flags[0] != '\0') execlp("ls","ls",NULL)
else execlp("ls","ls",NULL);
} else wait(0);
if(pipe_cmd[0] != '\0') // parent goes here, if pipe.
{
pipechild = fork();
if(pipechild != 0) // *PROBLEM ARISES HERE- IF THIS IS FORKED, IT WILL HAVE NO INFO TAKEN IN.
{
close(0); // closing normal stdin
dup(a[0]); // making our input come from the child above
close(a[1]); // close other end of pipe
if(file_name[0] != '\0') // if a filename does exist, we must reroute the output to the pipe
{
close(1); // close normal stdout
int fileredir_pipe = open(file_name, O_APPEND|O_WRONLY|O_CREAT, 0644);
dup2(fileredir_pipe, STDOUT_FILENO); //redirects STDOUT to file
execlp("wc","wc",NULL); // this outputs nothing
}
else
{
// else there is no file.
// executing the pipe in stdout using execlp.
execlp("wc","wc",NULL); // this outputs nothing
}
}
else wait(0);
}
提前致谢。对于某些代码被隐瞒,我深表歉意。这仍然是一项积极的任务,我不想要任何学术不诚实的案例。这个帖子风险太大了。
【问题讨论】:
-
不幸的是,没有minimal reproducible example,没有人能够确定发生了什么。关键部分是未显示的部分。
-
我遵循了第 2 部分,但如果需要,我可以尝试编写第二段代码。我删除了 pipechild 的子 fork() 代码并在没有它的情况下运行,并且由于某种原因,它工作得很好(减去 execlp() 应该杀死程序的事实)。我对此有点陌生,这还不够吗?
-
抱歉,不是。除非世界上任何人都能够剪切/粘贴显示的代码,完全如图所示,然后编译、运行和重现您的问题,否则它不是minimal reproducible example .直到您对以下问题回答“是”:我可以仅将问题中的内容剪切/粘贴到新文件中,编译,运行并得到相同的问题 - 直到该问题的答案为“是”,这不是minimal reproducible example.
-
好的,它已经编辑好了。它应该运行“ls | wc”,但“wc”部分没有从“ls”部分获得输入。希望能为您解决问题。
-
这仍然不是minimal reproducible example,因为剪切/粘贴确切显示的内容没有编译的机会。没有包含文件。没有
main,等等......不过,现在很明显这里出了什么问题......
标签: c pipe fork child-process