2016-03-18 41 views
-5
int main(void) { 
    char in[512]; 

    pid_t id; 
    int status, y, x, i = 1; 
    char *f[512]; 
    char *v; 

    while(1) 
    { 
     printf("shell>"); 
     fgets(in,512, stdin); 
     int size = strlen(in);// calculate dim of in execpt null 
     in[size-1] = '\0'; //null at the end because ls\n not executable 
     v = strtok(in, " "); 
     f[0] = v; 
     while (v = strtok(NULL, " ")) { 
      f[i] = v; 
      i++; 
     } 
     f[i] = NULL; 

     y = strcmp(f[0],"exit"); 

     if (y == 0) 
     break; 

     id = fork(); 

     if (id==0) { //child 
      execvp(f[0],f); 
      perror("failure"); 
      exit(1); 
     } 
     else //parent 
     { 
      x=strcmp(f[i-1],"&"); 
      if (x != 0) 
      waitpid(id, &status, 0); 
     } 
    } 
} 

在這段代碼中我可以執行shell命令,但是我不能執行command &部分。我怎樣才能讓execvp在後臺執行一個進程?執行後臺進程的Shell項目

+4

'if(f [0] ==「exit」)'。使用'=='運算符不能比較C中的字符串。需要使用'strcmp'。 – kaylum

+0

請學習使用編輯框左上角的格式化工具來保持代碼/數據/ errorMsgs/etc的格式。祝你好運。 – shellter

+1

這篇文章是不可讀的。請記住,如果一行以4個空格開頭,Stack Overflow會將其視爲代碼(並去掉這些空格)。要縮進,只需提供額外的空間。 –

回答

1

閱讀Advanced Linux Programming。使用strace(1)現有的程序(特別是shell)瞭解他們在做什麼system calls。查看syscalls(2)的清單並更準確地閱讀其中幾個文檔的文檔(請參閱intro(2) ...)。 研究一些現有的free software shell的源代碼,如sash & bash

不要忘記系統調用(例如您對fork(2) ...的調用)可能會失敗。你應該處理失敗,至少喜歡:

id = fork(); 
if (id<0) { perror("fork"); exit(EXIT_FAILURE); }; 

關於結束&的處理,你job control照顧。瞭解有關process groups的更多信息。

你的計劃沒有實現globbing或​​,並且不能帶參數運行的一些程序(例如命令ls a b應該運行/bin/ls與三個參數"ls""a""b"),因爲每個shell應該。見glob(7) & pipe(7)

不要指望我們做你的功課。你可能應該編寫一個更大的程序(可能是一千行,幾十個函數,幾個struct帶指針,....),並首先考慮它的設計(這是學習現有的 shell實現將幫助你)。特別要先在一張紙上(或一些白板)列出一套重要的功能和數據結構來實現。

我建議先編寫你的shell,以便能夠運行簡單的命令,如ls a b,實現globbing(所以接受ls *.c)。一旦完成並調試,考慮實施一些內建(特別是cd),作業控制和管道。在所有這些研究的一些現有的外殼的源代碼,當然,實現它的主要系統調用。

BTW,編譯所有的警告&調試信息(gcc -Wall -Wextra -g)和使用調試器gdb)非常頻繁。