提问人:Collin Meese 提问时间:10/1/2018 更新时间:10/1/2018 访问量:359
当 EOF 输入 C 时,Shell 会无休止地循环
Shell endlessly loops when EOF is entered C
问:
我是一个新的C程序员,正在尝试创建自己的shell。shell 本身运行良好并正确处理我的命令,但是当用户在命令行中输入 EOF 字符作为输入时,我的 shell 只是无限循环。我的代码以及我已经尝试过的内容发布在下面(我也是使用 GDB 和 Valgrind 的新手,但两者似乎都不能帮助我找到问题)。
我已经尝试过:
- 下面的当前实现尝试捕获 getline 的返回值,并处理它返回 -1 的情况(读取 EOF 时)。但是,这只会导致 shell 无休止地循环提示
我用以下代码完全替换了我的函数调用:
if (fgets(command_line, MAX_CANON, stdin) == NULL) { printf("\nTo quit, please use the exit command: exit.\n"); }
据我所知,上述替换应处理用户输入的 EOF 字符。但是,这种使用 fgets 的实现也会导致无休止的命令提示符循环。
以下是我目前的实现,在上面的 #1 中有所提及:
在 main 中调用的函数以读取用户的输入:
char *read_command_line(void)
{
//Declare an integer to hold the length of the string, a line to hold our output, and a variable getline can use to hold the generated buffer
int len;
char *line = NULL;
ssize_t bufsize = 0;
//Get the line from stdin
int retval = getline(&line, &bufsize, stdin);
if(retval == -1)
{
line = NULL;
return line;
}
//Determine the length of the line and set a null terminating byte to end the string and get rid of the trailing return
len = strlen(line);
line[len - 1] = '\0';
//Finally return the read in line
return line;
}
我的 shell while 循环的开头,其中读入了行:
//BEGIN SHELL
while (go)
{
//Signals are handled in the main.c
//Print the prompt
char cwd_loop[max_buf_size];
getcwd(cwd_loop, sizeof(cwd_loop));
printf("\n%s [%s]:> ", prompt_prefix, cwd_loop);
commandline = read_command_line();
if(commandline == NULL)
{
continue;
}
答:
1赞
chqrlie
10/1/2018
#1
当输入流已关闭时,不应继续提示和读取进一步的输入,如返回或返回所示。只需跳出循环,就好像输入了命令一样。getline()
-1
fgets()
NULL
exit
评论
0赞
Collin Meese
10/1/2018
谢谢,输入流关闭对我来说很有意义,我在上面没有考虑到这一点。是否可以重新打开输入流,然后在 while 循环中发出 continue,以便在用户输入 EOF 时,我们不会退出,而只是再次提示?我现在也会考虑自己重新打开封闭的输入流。再次感谢。
1赞
Some programmer dude
10/1/2018
#2
从您的代码
commandline = read_command_line();
if(commandline == NULL)
{
continue;
}
如果返回一个 null 指针,如果出现类似 的错误,它会这样做,那么你继续循环,让它再次迭代。这一次将再次返回一个空指针,并且您永远这样继续下去。read_command_line
EOF
read_command_line
如果返回 null 指针,则应断开
循环。read_command_line
评论
0赞
Collin Meese
10/1/2018
啊,好吧,这很有道理。我现在已经这样做了,以防止将来出现任何问题,但我的主要目标是以一种允许 shell 优雅地恢复提示用户而无需他们再次运行程序的方式实现处理。希望我能够通过更多的研究来解决这个问题。感谢您的建议
0赞
that other guy
10/1/2018
这相当于编写一个 GUI 工具,每次点击“文件 -> 退出”时都会“优雅地”重新启动,这样就不需要用户手动重新调用它。
评论
line[strlen(line) - 1]
似乎有点不对劲。根据定义,此操作不应更改任何内容。strlen
strlen
\0