1

我有一个项目需要我在 C 中构建一个简单的 shell。我是 C 的新手,我现在面临的问题是在发送命令执行之前正确解析命令。我知道有几种不同的方法可以做到这一点,但我们需要使用 strtok ,我似乎遇到了一些问题。

这是我的全部代码:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>

int parseCommands(char *command, char **args){
    int pos = 0;
    printf("%s\n", command);
    char *readCommand = NULL;
    char delims[] = {" \n"};
    readCommand = strtok(command, delims);
    while(readCommand != '\0'){
        printf("%s\n", readCommand); 
        strcpy(args[pos], readCommand);
        printf("%s\n", args[pos]);
        readCommand = strtok(NULL, delims);
        pos++;
    }
    return pos;
}

int executeCommand(char **args){
    pid_t pID;
    switch(pID = fork()){
        case 0:
            execvp(args[0], args);
            perror("Some sort of exec error");
            return -1;
        case -1:
            perror("Could not even fork");
            return -2;
        default:
            wait(NULL);
            return 0;
    }
}

void main(){

    char wd[256];
    char input[256];
    char *args[15];

    char strDelims[] = ";";
    char *readInput = NULL;

    while(1){

        getcwd(wd, sizeof wd);
        printf("mysh: %s> ", wd);
        fgets(input, sizeof input, stdin);

        readInput = strtok(input, strDelims);

        int numArgs;
        numArgs = parseCommands(readInput, args);
            if(numArgs < 1)
                printf("There was a problem parsing the command\n");

            if(strcmp(args[0], "cd") == 0){
                printf("%d\n", numArgs);
                if(numArgs > 1){
                    if((chdir(args[1])) < 0){
                        perror("I'm afraid I can't let you do that Dave\n");
                    }
                }
                else{
                    if((chdir(getenv("HOME"))) < 0){
                        perror("Can't go home\n");
                    }
                }
            }
            else if(strcmp(readInput, "quit") == 0){
                break;
            }
            else{
                if((executeCommand(args)) != 0)
                    printf("Problem executing the command\n");
            }
            readInput = strtok(input, strDelims);
    }

}

这是几个命令的输出:

mysh: /path/to/stuff> cd
cd

cd
cd
1
mysh: /path/to/home> cd /bin
cd /bin

cd
cd
/bin
/bin
2
mysh: /bin> ls
ls

ls
ls
Segmentation fault
mysh: /path/to/stuff> ps aux
ps aux

ps
ps
aux
aux
Segmentation fault

我只是觉得奇怪的是,它cd似乎工作得很好,但它并不真正喜欢其他任何东西。这让我认为稍后会出现问题(但在 numArgs 的 printf 之前?)。仅供参考,我们被告知每个命令不会超过 15 个参数或 256 个字符。

这让我沮丧了一段时间,所以对这个特定问题的任何帮助都会很棒(我意识到那里还有其他错误或糟糕的代码部分,但我想自己找出/修复这些)。非常感谢!:)

4

1 回答 1

3

一些指示

通常 strtok 共享一个静态缓冲区,因此当您在 parse 函数之前先调用 strtok ,然后在 parse 函数内部调用时,您可能会弄乱之前缓冲区中的内容。

您也没有为 args[] 分配空间,您只声明一个指针数组,(char *args[15]) 然后在您的解析函数中,您对指针指向的任何内容执行 strcpy。您需要分配一个缓冲区,分配给 args[i] 然后将字符串复制到其中。

所以而不是

strcpy(args[pos], readCommand);

args[pos] = strdup(readCommand);
于 2012-10-01T21:11:35.430 回答