我目前正在創建自己的命令行shell,並且在嘗試使用管道時遇到問題。我的程序從父進程開始。它檢查用戶是否放入退出或歷史記錄。如果是這樣,它使用這些命令,但這並不重要。如果用戶輸入除退出或歷史以外的任何內容,則會創建一個執行當前任務的孩子。爲什麼不打印到標準輸出(stdout)?
但是,如果用戶輸入一個具有單個管道的命令,那麼我們從父進程開始,它創建一個子進程,調用這個子進程,子進程1.子進程1看到有一個管道並使用fork創建另一個孩子,稱這個孩子2.孩子1創建另一個孩子,稱它爲孩子3(注意:孩子2和3使用共享內存)。現在,孩子2執行第一個命令,孩子3使用孩子2的輸出執行命令。但由於某種原因我沒有得到任何輸出。
我不確定這是否是執行我的任務的最有效的方式,但這是我的教授說要做的。
如果你想看到我所有的代碼在這裏,它是:http://pastebin.com/YNTVf3XP
否則這裏是我的代碼開始在孩子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);
}
}
}
我認爲你有太多的孩子。如果你有'foo |酒吧'你需要一個管道和兩個更多的過程(除了你的程序已經是)。所以父母創建一個管道,'p'父母爲第一個孩子(這將是'bar')分叉。孩子:'close(p [1]); dup2(p [0],0); exec(「bar」);'現在父母分叉第二次(這將是'foo')。 Child:'close(p [0]); dup2(p [1],1); exec(「foo」);'Parent:'close(p [0]);靠近[P [1]);等待孩子'。 –
@ J.V.A。我在問題中添加了一張圖片,顯示了我的教授給我的東西。這不意味着總共應該有3個孩子嗎?然而,我可能是錯的。 – Logan
我不確定shell(1)在做什麼,但如果教授想要這樣做,那麼這就是正確的答案:) –