我正在用C编写自己的简单shell for Linux。我无法在不退出整个shell的情况下实现管道。我相信我需要再实现一个fork()来实现这个目标,但我不知道该怎么做。
我的程序有一个main():
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(void){
char input[256];
char* temp = NULL;
char* args[9];
char* cmd1[5];
char* cmd2[5];
int i, j, pipe_pos;
int fd[2];
while(1){
// set all args to NULL
for (i = 0; i < 9; i++) {
args[i] = NULL;
}
for (i = 0; i < 5; i++) {
cmd1[i] = NULL;
cmd2[i] = NULL;
}
// print message to terminal
printf("My Shell (v2.0):> ");
// get input from user
fgets(input,255,stdin);
// test if input = 'quit'
if (!strncmp(input,"quit",4)) {
// exit program if input = quit
exit(0);
}
else { // continue running program
// initialise counter
i = 0;
// tokenize first word
temp = strtok(input, " \n");
// receive arguments from user input
while ((temp != NULL) && (i < 9)) {
args[i] = temp;
temp = strtok(NULL, " \n");
i++;
}
// find position of "|" (pipe)
j = i - 1;
pipe_pos = 8;
for (i = 0; i < j; i++) {
if (strcmp(args[i],"|") == 0) {
pipe_pos = i;
break;
}
}
// copy 1st command with arguments to new array
for (i = 0; i < pipe_pos; i++) {
cmd1[i] = args[i];
}
// copy 2nd command with arguments to new array
j = 0;
if (pipe_pos != 8) {
for (i = pipe_pos+1; i < 9; i++) {
// copy if array is not full
if (j < 5){
cmd2[j] = args[i];
j++;
} // end if (j < 5)
} // end for
} // end if (pipe_pos != 8) {
// run if program needs piping
if (pipe_pos != 8) {
pipeProcesses(cmd1, cmd2);
}
else {
runProcess(cmd1);
}
} // end else
}// end while
return 0;
}// end main()
pipingProcesses()函数:
void pipeProcesses(char ** cmd1, char ** cmd2){
int fd[2];
pipe(fd);
if (!fork()) {
// close STD_OUT
close(1);
// make STD_OUT same as fd[1]
dup(fd[1]);
// we don't need this
close(fd[0]);
runProcess(cmd1);
exit(0);
} else {
// close STD_IN
close(0);
// make STD_IN same as fd[0]
dup(fd[0]);
// we don't need this
close(fd[1]);
execvp(cmd2[0], cmd2);
}
}
和runProcess()函数:
void runProcess(char ** cmd){
int error;
// initialise error flag
error = 0;
if (fork() == 0) {
// child process
error = execvp(cmd[0], cmd);
// print error: unknown command
if (error == -1) {
printf("ERROR: UNKNOWN COMMAND (%s)\n", cmd[0]);
exit(0);
}
}
else {
// parent process
waitpid(0,NULL,0);
}
}
一切都按原样运行,除了我希望shell在管道输出两个命令后继续运行。我该如何解决这个问题?
答案 0 :(得分:1)
您在主程序流程中调用execvp(cmd2[0], cmd2);
,用cmd2
替换您的程序。
你也应该为该命令fork()。