2010-10-26 51 views
2

我新的C和我試圖創建一個簡單的C shell中,將允許用戶執行像CHDIR,CD,退出的mkdir各種功能。幫助創建一個簡單的C殼

我下面貼出我的代碼。任何人都可以看穿它,看看我做錯了什麼?我不確定我是否正確使用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

你能告訴我們的行爲是什麼? – BobbyShaftoe 2010-10-26 02:27:13

+0

它運行並循環回來提示我只是不認爲它執行的命令。 – 2010-10-26 02:42:20

+2

首先,你的格式化縮進是非常不一致的,這使得難以閱讀代碼。第二,你是什麼意思,「我做錯了什麼?」?什麼不行?你期望什麼,你究竟得到了什麼? Fer就是這樣,你甚至不會告訴我們它是否有編譯時/鏈接時間/運行時錯誤!我們不通過ESP進行調試。 – abelenky 2010-10-26 02:45:44

回答

3

至少國際海事組織,你對main投入太多了。我喜歡的東西開始:

int main() { 
    char input[128]; 

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

然後dispatch會尋找內部命令,只有做一個exec當/如果它給它不能識別的命令。爲了簡單起見,開始時,你可以考慮使用popen執行外部命令,並留下切換到「原始」叉/ EXEC用於以後,當popen開始的侷限性,造成問題。

0

對於shell內建(man bash),你可能不希望到餐桌/ EXEC。我將保存fork/exec以運行PATH中的程序(您的shell必須管理的環境變量)。 shell本身應該通過像chdirman 2 chdir)這樣的命令與文件系統連接。

考慮使用一個不錯的字符串標記(或者只是退回到strtok函數)解析命令行中,作爲另一意見建議,即抽象成一個功能,讓你的主循環是瘦肉。