我正在尝试在C中实现一个基本的shell,但每当我的shell使用execvp()执行一个命令时,它就会跳出我希望它保留的循环。我怀疑这是因为我不是熟悉execvp。
相关代码:
int main()
{
int nCmd = 1; // Command number
char *line; // Initial command line
token *list; // Linked list of tokens
CMD *cmd; // Parsed command
int process (CMD *);
for ( ; ; ) {
printf ("(%d)$ ", nCmd); // Prompt for command
fflush (stdout);
if ((line = getLine (stdin)) == NULL) // Read line
break; // Break on end of file
list = lex (line);
// Lex line into tokens
free (line);
if (list == NULL) {
continue;
} else if (getenv ("DUMP_LIST")) { // Dump token list only if
dumpList (list); // environment variable set
printf ("\n");
}
cmd = parse (list); // Parsed command?
freeList (list);
if (cmd == NULL) {
continue;
} else if (getenv ("DUMP_TREE")) { // Dump command tree only if
dumpTree (cmd, 0); // environment variable set
printf ("\n");
}
process (cmd); // Execute command
freeCMD (cmd); // Free associated storage
nCmd++; // Adjust prompt
}
return EXIT_SUCCESS;
}
以下是“流程”的相关部分:
int process (CMD *cmdList)
{
if ((cmdList->nLocal)>0)
{
for (int i = 0; i<cmdList->nLocal; i++)
{
setenv(cmdList->locVar[i], cmdList->locVal[i], 0);
}
}
if (cmdList->type==SIMPLE)
{
execvp(cmdList->argv[0],cmdList->argv);
}
return 0;
}
正在发生的事情是我在main的for循环中完成了第一个过程。但是,执行命令后,程序才会结束,而不是像我想的那样读取命令行。如何让它保持在for循环中?
答案 0 :(得分:2)
execvp
将当前流程替换为您要求其运行的流程。
您需要使用fork
创建子进程并从子进程运行execvp
。这样,父母将仍然活着并且能够处理更多用户输入。
答案 1 :(得分:1)
exec*
形式的函数族是唯一的,因为只要程序到达它们,整个过程存储器就被擦除并用新程序的过程存储器重写。你的代码没有跳出循环,循环不再存在。
如果要模仿shell的工作方式,则必须使用另一个系统调用来创建可以覆盖的单独进程:fork
。查找更多信息。