帮助创建一个简单的C shell

时间:2010-10-26 02:25:58

标签: c shell

我是C的新手,我正在尝试创建一个简单的C shell,允许用户执行各种功能,如chdir,cd,exit,mkdir。

我在下面发布了我的代码。任何人都可以通过它看看我做错了什么?我不确定我是否正确使用forkexeccv。谢谢!

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

main() {
    //char *user;

    //if ((user = getlogin()) == NULL)
    //    perror("__getlogin1() error");
    //else printf("__getlogin1() returned %s\n", user);
    int j, status;
    int pid, c_pid;
    int i = 0;
    char *tmp, **ap;
    char instring[80]; // store one line of input
    char *argv[10]; // store parameters in the format for execv()

    promptstart:

    printf("Please enter a commcand:\n");

    // read a char at a time and put it in instring[]
    // put a '\0' at the end
    instring[i] = getc(stdin); // stdin is the keyboard
    while (instring[i] != '\n') {
        i++;
        instring[i] = getc(stdin);
    }
    instring[i] = '\0'; // replace '\n' with '\0'

    tmp = instring;
    i = 0;
    argv[i] = strsep(&tmp, " \t"); // put first word int argv[0]
    while ((i < 10) && (argv[i] != '\0')) {
        i++;
        argv[i] = strsep(&tmp, " \t");
    }

    // print out the command and options.
    i = 0;
    while (argv[i] != '\0') {
        printf("your entered: %s\n", argv[i++]);
    }

    //PLACE ERROR HERE

    if ((c_pid = fork()) == 0) {
        for (j = 0; j < 10; j++)
            printf("child (%d) prints %d\n", getpid(), j);
        exit(0);
    } else if (c_pid > 0) {
        c_pid = wait(&status);
        printf("child %d exited with status %d\n", c_pid, status);
    } else {
        execvp(argv[0], argv);

    }
    goto promptstart;
}

2 个答案:

答案 0 :(得分:3)

至少IMO,你在main投入了太多。我会从以下内容开始:

int main() { 
    char input[128];

    do { 
        fgets(stdin, input, sizeof(input));
        dispatch(input);
    } while (strcmp(input, "exit"));
    return 0;
}

然后dispatch会查找内部命令,并且只有在{/ 1}}给出一个它无法识别的命令时才会执行exec。为了简单起见,您可以考虑使用popen执行外部命令,并在popen的限制开始导致问题时,切换到“原始”fork / exec以供日后使用

答案 1 :(得分:0)

对于shell builtins(man bash),你可能不想fork / exec。我会保存fork / exec来运行PATH中的程序(shell必须管理的环境变量)。 shell本身应该通过chdirman 2 chdir)等命令与文件系统连接。

考虑使用一个好的字符串标记器(或者只是回退到strtok)来解析命令行,并且正如另一个注释所暗示的那样,将它抽象到一个函数中,以便你的主循环是精简的。