【问题标题】:Creating Simple Shell in Linux在 Linux 中创建简单的 Shell
【发布时间】:2019-03-27 04:27:41
【问题描述】:

我正在执行一项任务,用 C 语言创建一个极其简单的 Linux shell,它几乎完全按照我想要的方式工作。

如果用户输入一个简单的 Linux 命令,程序将运行它并循环以允许另一个命令。如果用户输入“quit”,则程序退出。

我的问题是这些命令只能在第一次工作。之后,它们似乎以某种方式变得格式不正确。有没有办法重新初始化我的 args 数组,以便它正确接收新输入?

int main() {
    char* args[50];          // Argument array.
    char userInput[200];     // User input.
    char* userQuit = "quit"; // String to be compared to user input to quit program.
    int pid;                 // Process ID for fork().
    int i = 0;               // Counter.

    while(1) {
        // Promt and get input from user.
        printf("minor5> ");
        fgets(userInput, sizeof(userInput), stdin);

        // Pass userInput into args array.
        args[0] = strtok(userInput, " \n\0");

        // Loop to separate args into individual arguments, delimited by either space, newline, or NULL.
        while(args[i] != NULL) {
            i++;
            args[i] = strtok(NULL, " \n\0");
        }

        // If the first argument is "quit", exit the program.
        if(strcmp(args[0], userQuit) == 0) {
            printf("Exiting Minor5 Shell...\n");
            exit(EXIT_SUCCESS);
        }

        // Create child process.
        pid = fork();

        // Parent process will wait for child to execute.
        // Child process will execute the command given in userInput.
        if(pid > 0) {
            // Parent //
            wait( (int *) 0 );
        } else {
            // Child //
            int errChk;
            errChk = execvp(args[0], args);

            if(errChk == -1) {
                printf("%s: Command not found\n", userInput);
            }
        }
    }

    return 0;
}

【问题讨论】:

    标签: c arrays linux shell strtok


    【解决方案1】:

    您需要确保 args 的最后一个值为 NULL。它可能在 first 命令上有一个,偶然,但不能保证

    这是您的解析循环的重新设计的 sn-p [请原谅无端的样式清理]:

    // Pass userInput into args array.
    char *uptr = userInput;
    
    i = 0;
    while (1) {
        char *token = strtok(uptr, " \n");
        uptr = NULL;
    
        if (token == NULL)
            break;
    
        args[i++] = token;
    }
    
    // NOTE: this is the key missing ingredient from your code
    args[i] = NULL;
    

    【讨论】:

    • 对不起,为什么你认为他的代码中的args 不能保证有NULL 最后一个值?这个条件while(args[i] != NULL) 保证,不是吗?另一件事是他没有将他的i 重置为 0
    • 此代码导致第二次尝试输入命令时出现分段错误。
    • @mangusta 谢谢老兄。我没有注意到我忘记重置我的计数器。这就是整个问题。它现在完美运行!谢谢。
    • @mangusta 不,它没有。拉取 OP 的代码并运行它。做:ls /etc/passwd。然后执行:vi [没有任何参数]。你会看到它通过了:vi "" 而不是 no 参数。尝试使用手册vi 供参考
    猜你喜欢
    • 2015-01-13
    • 2011-04-07
    • 2012-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多