我试图用C制作自己的shell,但是我在处理后台和前台进程时遇到麻烦。这是我创建流程的地方:
void call_exec(char *cmd)
{
pid_t cpid;
is_Background();
if(index(cmd, '/') == NULL) {
int i;
printf("cmd is %s\n", cmd);
cpid = fork();
if(cpid == 0) {
i = execvp(cmd, my_argv);
if(i < 0) {
printf("%s: %s\n", cmd, "command not found");
exit(1);
}
}
else {
if(!is_BG ) {
wait(NULL);
}
is_BG = 0;
}
}
is_Background:
void is_Background() {
if(strcmp(my_argv[arg_index], "&") == 0) {
is_BG = 1;
my_argv[arg_index] = NULL;
}
}
当我运行代码并在命令行中输入“gedit”时,shell会一直等到我关闭gedit窗口,然后提示我输入新命令。当我输入“gedit&”在后台运行gedit时,它工作正常,gedit窗口打开,shell立即提示我输入新命令,而无需等待关闭gedit窗口。问题是,在我仅对任何命令使用“&”一次之后,shell就再也不会等待任何前台进程结束/关闭了。例如,如果我输入不带“&”的“gedit”或“firefox”,shell不会等待它们关闭。
我希望我能够正确地解释我的问题,我的英语不好,所以对不起我的错误。如果我需要提供更多信息,请告诉我。谢谢。
最佳答案
这里有两个问题:
首先,gedit和firefox是单实例程序。任何其他调用都将仅重用现有实例。您会在bash中看到相同的内容:
bash$ gedit & # Starts gedit and returns immediately
bash$ gedit # Opens a new tab in the existing window and returns immediately
您应该使用多个实例程序(例如
xterm
或xeyes
)进行测试。其次,您的
wait(NULL)
调用等待任何进程关闭,而不必等待最后一个进程。在您的 shell 中,您可能会看到以下内容:yourshell$ xterm & # starts xterms and returns immediately.
# Now close the xterm before running the next command
yourshell$ xeyes # starts xeyes, waits on xterm, returns immediately
您可以改为使用
waitpid(cpid, NULL, 0)
等待正确的过程。