gpt4 book ai didi

c - 为什么这不打印到标准输出 (stdout)?

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

我目前正在创建自己的命令行 shell,但在尝试接收管道时遇到了问题。我的程序从父进程开始。它检查用户是否输入了退出或历史记录。如果是这样,它会使用那些命令,但这并不重要。如果用户输入除 exit 或 history 以外的任何内容,则它会创建一个执行当前任务的 child 。

但是,如果用户输入一个只有一个管道的命令,那么我们从父进程开始,它创建一个子进程,调用这个子进程,child 1。child 1 看到有一个管道并使用 fork 来创建另一个 child ,称这个 child 为2。 child 1创建另一个 child ,称其为 child 3(注意: child 2和3使用共享内存)。现在, child 2 执行第一个命令, child 3 使用 child 2 的输出执行命令。但由于某种原因我没有得到任何输出。

我不确定这是否是执行任务的最有效方式,但这是我的教授所说的。

如果你想在这里看到我的所有代码,它是:http://pastebin.com/YNTVf3XP

否则这里是我的代码从 child 1 开始:

            //Otherwise if we have a single pipe, then do
else if (numPipes == 1) {

char *command1[CMD_MAX]; //string holding the first command
char *command2[CMD_MAX]; //string holding the second command
int fds[2]; //create file descriptors for the parent and child
pid_t new_pid; //create new pid_t obj

onePipeSplit(tokens, command1, command2, numTokens); //Getting each command for pipe

if (pipe(fds) < 0) { //use the pipe command. If < 0
perror("Pipe failure."); //we have an error, so exit
exit(EXIT_FAILURE);
}

//Creating child 2
new_pid = fork();

//if pid < 0 then we have an error. Exit.
if (new_pid < 0) {
perror("Fork failure.");
exit(EXIT_FAILURE);
}

//Else we have the child (2) process
else if (new_pid == 0) {

close(fds[0]); //Close read

//sending stdin to the shared file descriptor
if (dup2(fds[1], STDOUT_FILENO)<0) {
perror("Can't dup");
exit(EXIT_FAILURE);
}

execvp(command1[0], command1); //Execute the next command
perror("Exec failure");
exit(EXIT_FAILURE);
}

//Else if we have the parent process
else {

pid_t child = fork(); //Creating child 3
if (new_pid < 0) { //if pid < 0, error, exit
perror("Fork failure.");
exit(EXIT_FAILURE);
}

//else if pid > 0 we have the parent wait until children execute
else if (new_pid > 0) {
wait(NULL);
}

//else we have the child (3)
else {

close(fds[1]); //Close write

//Sending stdout to the shared file descriptor
if (dup2(fds[0], STDIN_FILENO) < 0) {
perror("Can't dup");
exit(EXIT_FAILURE);
}

execvp(command2[0], command2); //Execute the command
perror("Exec failure");
exit(EXIT_FAILURE);
}
}
}

这是我的教授给我的一张图片,用来展示它应该如何工作。 pipe

最佳答案

问题出在这里:

                   pid_t child = fork();           //Creating child 3
if (new_pid < 0) {
... you keep checking `new_pid` here on down,
... but you should be checking `child` here on down...

此外,在 onePipeSplit 中,您需要在两个命令列表的末尾放置一个 NULL,因为 execvp 需要它。在第一个循环后添加:

command1[i] = NULL;

第二个之后:

command2[i] = NULL;

好的,还有一些修复:

在每个 dup2() 之后你需要关闭原来的 fd。一个例子:

                    if (dup2(fds[1], STDOUT_FILENO)<0) {
perror("Can't dup");
exit(EXIT_FAILURE);
}
close(fds[1]); /* ADD ME */

在父进程中:

                    //else if pid > 0 we have the parent wait until children execute
else if (child > 0) {
close(fds[0]); /* we don't use */
close(fds[1]); /* the pipe */
wait(NULL);
exit(0); /* when 2 & 3 are done, we are too */
}

关于c - 为什么这不打印到标准输出 (stdout)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35251154/

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