使用 Read 系统调用时 While 循环不会退出

While Loop Won't Exit While Using Read System Call

我正在构建一个使用 linux 系统调用充当 shell 的基本程序。现在我正试图让它以字符串形式读取输入,以便我可以根据需要修改信息。当我 运行 程序并从终端给它一些输入时,它会继续挂起。我猜我的 while 循环不会结束,但我不确定为什么。任何和所有帮助将不胜感激。

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char ** argv) {
    int i;

    char prompt[3] = "sh#";
    char input[256];
    char inputc;

    /*print out prompt */
    write(1, &prompt, sizeof(prompt));

    i = 0;
    while(read(0, &inputc, 1) != 0) {
        input[i] = inputc;
        i++;
    }
    input[i] = '[=10=]';  /* null terminator */
    printf("%s\n", input);  

    return 0;
}

您应该使用 getline() 而不是 read()。因为 getline() 为您做了很多工作。此外,如果您只想从输入中接收 1 行,则只需使用 read()getline(),而不使用您建立的 while() 循环。 while 循环对于多个输入是最必要的,这就是我假设您想要的,因为您将其称为 shell 类型的程序并且您的提示字符串中包含 sh

如果你想在代码中使用 read(),那么你应该创建自己的 getline() 使用 read()。这可能是您自己的 my_getline() 循环使用 read() 函数代码的示例,您应该根据需要添加要中断的条件。

char *inputc, input[256];
int i;
for (i = 0; (read(STDIN_FILENO, inputc, 1) != EOF); i++)
{
    input[i] = inputc[0];
}

我已使用此修复程序修改了您的代码并删除了不必要的变量。您没有使用 argc**argv,所以它们也被删除了。 while 循环使用 getline() 而不是 read()。该字符串在每个输入行之后打印。当输入字符串为:"quit" 时,mini-shell 终止。如果您想在没有输入的情况下终止,您也可以为此添加修改。

$ cat main.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
    size_t size = 256;
    char prompt[5] = "sh$ ";
    char *inputc = NULL;
    /* print out prompt */
    write(1, &prompt, 4);
    while(getline(&inputc, &size, stdin) != -1)
    {
        /* check if input is "quit" to terminate the mini shell */
        if (strncmp(inputc, "quit", 4) == 0)
            break;
        /* prints the input */
        printf("%s", inputc);
        /* re-print out prompt to continue loop*/
        write(1, &prompt, 4);
    }
    printf("%s\n", inputc);
    return 0;
}

在您的终端中输出(第三个输入只是换行符 '\n' 或 [RTN] 按钮,没有输入,也没有打印任何内容:

$ gcc -Wall -Werror -Wextra -pedantic main.c
$ ./a.out 
sh$ This is a test
This is a test
sh$ See how well getline works!
See how well getline works!
sh$ 

sh$ quit
quit


$