【发布时间】:2010-10-31 04:45:35
【问题描述】:
我创建了一个question about this a few days。我的解决方案与已接受答案中建议的内容一致。但是,我的一个朋友提出了以下解决方案:
请注意,代码已经更新了几次(检查编辑修订)以反映以下答案中的建议。如果您打算给出一个新的答案,请记住这个新代码,而不是有很多问题的旧代码。
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char *argv[]){
int fd[2], i, aux, std0, std1;
do {
std0 = dup(0); // backup stdin
std1 = dup(1); // backup stdout
// let's pretend I'm reading commands here in a shell prompt
READ_COMMAND_FROM_PROMPT();
for(i=1; i<argc; i++) {
// do we have a previous command?
if(i > 1) {
dup2(aux, 0);
close(aux);
}
// do we have a next command?
if(i < argc-1) {
pipe(fd);
aux = fd[0];
dup2(fd[1], 1);
close(fd[1]);
}
// last command? restore stdout...
if(i == argc-1) {
dup2(std1, 1);
close(std1);
}
if(!fork()) {
// if not last command, close all pipe ends
// (the child doesn't use them)
if(i < argc-1) {
close(std0);
close(std1);
close(fd[0]);
}
execlp(argv[i], argv[i], NULL);
exit(0);
}
}
// restore stdin to be able to keep using the shell
dup2(std0, 0);
close(std0);
}
return 0;
}
这模拟了一系列通过管道的命令,如 bash,例如:cmd1 |命令2 | ... | cmd_n。我说“模拟”,因为如您所见,命令实际上是从参数中读取的。只是为了节省时间编写一个简单的 shell 提示符...
当然,还有一些问题需要修复和添加,例如错误处理,但这不是重点。我想我有点明白代码,但它仍然让我很困惑这整个事情是如何运作的。
我是否遗漏了什么,或者这确实有效,并且它是解决问题的好而干净的解决方案?如果没有,谁能指出这段代码存在的关键问题?
【问题讨论】:
-
这段代码应该做什么?
-
抱歉,我已经编辑了帖子以反映对代码的简单描述。
-
我开始认为您需要退后一步,将其拆分为各个组成部分,以清晰的功能拆分,而不是将其全部构建为一个不断增长的 hack。一旦您可以识别出一些合适的抽象和不变量,逻辑就会变得更加清晰。再一次,我相信我的 patch-tag.com/r/xsh 简单的 shell 示例是一个很好的模型。
-
就像我之前说的,你的 shell 比我需要的要多。我已经很困惑了……