【发布时间】:2014-02-09 05:19:38
【问题描述】:
我正在编写一个 C 程序来模拟一个简单的 shell。这个 shell 基本上会像任何其他 shell(ls、cat 等)一样评估命令,以及处理流水线和重定向。
目前,我正在尝试从获取用户输入、对其进行标记并执行提供的命令开始(例如,仅执行“ls”而不是“ls -l”)。但是,我在分叉时遇到了很多困难。似乎每次我分叉时,都会出现问题并创建数百个相同的进程,导致我的计算机死机并且我不得不重新启动。代码似乎是正确的,但我不知道是什么导致了这种行为。以下是我的代码的相关部分(主要方法和输入标记器方法)。
int main() {
char inputLine[512]; //user input
char *args[10]; //arguments
char* pathVar = "/bin/";//path for argument
char programPath[512]; //pathVar + args[0]
int n; //count variable
//loop
while (1) {
//print prompt, get input
printf("input> ");
fgets(inputLine, 512, stdin);
n = tokenizer(inputLine, args);
//fork process
pid_t pid = fork();
if (pid != 0) { //if parent
wait(NULL);
} else { //if child
//format input for execution
strcpy(programPath, pathVar);
strcat(programPath, args[0]);
//execute user command
int returnVal = execv(programPath, args);
}
}
return 0;
}
int tokenizer(char *input, char *args[]) {
char *line; //current line
int i = 0; //count variable
line = input;
args[i] = strtok(line, " ");
do {
i++;
line = NULL;
args[i] = strtok(line, " ");
} while (args[i] != NULL);
return i;
}
【问题讨论】:
-
“出错”是什么意思?您是否尝试过在 exec 中使用更简单的方法(或替换 exec)来隔离问题?您是否尝试打印出 programPath 以确保它是您认为应该的样子?
-
您显示的代码中似乎没有任何内容会导致您描述的内容。
-
实际上,您应该测试
fork的返回值是否有错误(-1),并且您还应该在execv之后exit以防万一它失败(尽管保存它的返回值是无用的,因为如果成功则不会返回,如果失败则总是返回 -1)。 -
我注意到的一件事是,因为
fgets将换行符留在字符串中并且您没有将其解析出来,所以您正在尝试exec类似“ls\n”的东西。这似乎也让我的系统感到头晕目眩。我不确定什么我的系统在做什么,但是磁盘开始像疯了一样颠簸,在我把它彻底关闭之前我永远无法控制系统。我要去睡觉了,但如果你还没有解决它,我感到很勇敢,我会在早上再看一遍。 -
@Duck 好一个! @user41419 您可以通过在
strtok分隔符中添加换行符来最轻松地解决 Duck 发现的问题。