我想用管做一个简单的shell。 我想我几乎做到了,但它没有回到主要。 我认为执行官没有完成。 以下是我的代码的一部分。 我将命令解析为如下定义的struct块。 符号类型5表示它具有| 。 当我运行这个程序时, this is result image.当我不使用烟斗时,它返回并打印>再次,但当我使用管道时它不会。
typedef struct Command {
char *file; // file to execute
char **arglist; // argument list to executable
SymbolType symbolType; // command seperator
int status; // exit code of the commnad
struct Command *next, *prev;
} Command;
void GetPipe(Command *command, int *fd){
SymbolType symbol = command->symbolType;
if(symbol==5){
close(1);
close(fd[0]);
dup2(fd[1],1);
}
if((command->prev)!=NULL) symbol=command->prev->symbolType;
if(symbol==5){
close(0);
close(fd[1]);
dup2(fd[0],0);
}
}
void ExecuteCommand(Command *command){
int fd[2];
pipe(fd);
for(;command!=NULL;command=command->next){
pid_t pid = fork();
if(pid<0) exit(1);
else if(pid==0){
GetPipe(command, fd);
if (execvp(command->file, command->arglist)==-1){
command->status=status_failure; exit(1);}}
else {
int status;
//waitpid(pid, &status, 0);
wait(&status);
}
}
close(fd[0]);
close(fd[1]);
}
int main(void){
Command *head = NULL;
int should_run = 1;
while (should_run){
printf("> ");
fflush(stdout);
GetCommandChain(&head);
ExecuteCommand(head);
DeleteCommandChain(head);
}
}
答案 0 :(得分:2)
。我认为执行官没有完成。
exec
系列调用用一个新的地址空间替换进程的整个地址空间,命令为exec
&#d; d。它不会回来。话虽如此,您的子代码看起来还不错。
一个潜在的问题是父进程对管道的读取端没有做任何事情。因此命令会将其输出写入管道,然后,当缓冲区已满时,它将阻止写入等待读取某些数据的内容。
另一个潜在的问题是,你永远不会在命令的标准输入中写任何东西。如果期望输入,它将永远阻止读取。
我认为你需要做的是将链中每个命令的stdout传递给链中下一个命令的stdin(也可能根据它的含义将一些输入放入第一个命令)。