我正在使用“int flag = [0或1]”来确定我的循环是否应该返回到do {}。 继承我的代码
void shell()
{
int flag = 1;
do
{
// Retrieve PID of the parent process.
pid_t shell_pid = getpid();
// Print shell prompt.
printf("{%i}$ ", shell_pid);
// Retrieve input from stdin.
char* input = NULL;
size_t input_size = 0;
getline(&input, &input_size, stdin);
char delim = ' ';
char **argvp;
int argc = makeargv(input, &delim, &argvp);
// Remove \n from last arg
char* lastarg = argvp[argc - 1];
while(*lastarg && *lastarg != '\n')
lastarg++;
*lastarg = '\0';
// Create a child process to handle user input.
pid_t pid = fork();
// Parent process.
if (pid != 0)
{
wait(NULL);
}
else // Child process
{
int i;
// Handle user input here!
//got some debugging tools here
printf("========DEBUG==========\n");
printf("There are %i args\n", argc);
for(i = 0; i < argc; i++)
{
printf("arg %i: \"%s\"\n", i, *(argvp + i));
}
printf("=====END DEBUG==========\n\n");
printf("********OUTPUT*********\n");
//handle "echo" here
if((i = strcmp(argvp[0],"echo")) == 0)
{
echo(argc, argvp);
}
//handle "exit" or "quit" here
if((i = strcmp(argvp[0],"exit")) == 0 || (i = strcmp(argvp[0],"quit")) == 0)
{
printf("got in the exit\n");
flag = 0;
}
}
printf("****END OUTPUT*********\n");
// Free memory allocated by getline().
free(input);
}while(flag == 1);
}
我的输入/输出如下所示:[输入前面是$]
$ ./shelltest
{13158}$ try first string
========DEBUG==========
There are 3 args
arg 0: "try"
arg 1: "first"
arg 2: "string"
=====END DEBUG==========
********OUTPUT*********
****END OUTPUT*********
{13159}$ echo try another
========DEBUG==========
There are 3 args
arg 0: "echo"
arg 1: "try"
arg 2: "another"
=====END DEBUG==========
********OUTPUT*********
try another
****END OUTPUT*********
{13160}$ quit
========DEBUG==========
There are 1 args
arg 0: "quit"
=====END DEBUG==========
********OUTPUT*********
got in the exit
****END OUTPUT*********
****END OUTPUT*********
{13160}$
由于输出中显示“get in the exit”,因此flag立即设置为0。 循环如何继续?
答案 0 :(得分:4)
您正在使用fork()
,父进程正在等待子进程退出,该行:
printf("****END OUTPUT*********\n");
由父进程和子进程执行,因此您看到它两次。
答案 1 :(得分:1)
您的子进程正在退出循环,但您的父级继续运行。
shell的正常范例是父级读取和评估输入,只有在需要子进程时才进行分叉。
使用该方法,父级将检测exit
并完成而不创建子级。
答案 2 :(得分:1)
打印时
{13160} $ quit
实际上,13160是由fork创建的进程的父进程的pid来处理quit命令(要查看此操作,请在fork之后打印子进程的pid)。这个将通过将标志设置为0来解析退出并退出。然后,您将看到****END OUTPUT*********
两次。
你必须记住,当你分叉时,内存不与父共享(在Linux中它是,但它是写入时的副本。这是我上次读它时)所以当孩子写flag = 0时,父将没有看到这个值,所以它会再次循环。因此,为什么它再次要求输入。
您处理关系的另一件事看起来像{13158}->{13159}->{13160}->...
由于根进程是13158,我认为您想要做的是在每次输入后从root生成一个子进程。所以你可能想检查一下。