ç

2011-10-20 37 views
0

我試圖運行一個小的shell程序的第一步,以確保我的代碼正常運行shell程序的管道是確保我得到正確的命令和參數:ç

//Split the command and store each string in parameter[] 
    cp = (strtok(command, hash));      //Get the initial string (the command) 
    parameter[0] = (char*) malloc(strlen(cp)+ 1);      //Allocate some space to the first element in the array 
    strncpy(parameter[0], cp, strlen(cp)+ 1); 
    for(i = 1; i < MAX_ARG; i++) 
    { 
    cp = strtok(NULL, hash);     //Check for each string in the array 
    parameter[i] = (char*) malloc(strlen(cp)+ 1); 
    strncpy(parameter[i], cp, strlen(cp)+ 1);      //Store the result string in an indexed off array 
     if(parameter[i] == NULL) 
     { 
      break; 
     } 
    if(strcmp(parameter[i], "|") == 0) 
    { 
     cp = strtok(NULL, hash); 
     parameter2[0] = (char*) malloc(strlen(cp)+ 1); 
     strncpy(parameter2[0], cp, strlen(cp)+ 1); 
     //Find the second set of commands and parameters 
     for (j = 1; j < MAX_ARG; j++) 
     { 
      cp = strtok(NULL, hash); 
      if (strlen(cp) == NULL) 
      { 
       break; 
      } 
      parameter2[j] = (char*) malloc(strlen(cp)+ 1); 
      strncpy(parameter2[j], cp, strlen(cp)+ 1); 
     } 
     break; 
    } 

我有當我比較cp和NULL時出現問題,我的程序崩潰了。我想要退出循環,一旦第二組或參數的條目已經完成(這是我試圖用if(strlen(cp)== NULL)做的事

+0

「小殼程序」? –

+0

另請參閱密切相關的問題[Unix shell C執行管道](http://stackoverflow.com/questions/7830160/unix-shell-c-execution-of-pipe)。 –

回答

1

我可能誤解了這個問題,但你的程序永遠不會看到管道符,|

外殼處理整個命令行,你的程序將只給它的命令行的份額,可以這麼說。

例:

​​

在上面的示例中,僅使用兩個參數file1file2來調用cat。另外,僅用一個參數調用seds/frog/bat/

+0

它完全取決於提問者所說的「小型shell程序」。 –

0

讓我們看看你的代碼:

parameter[0] = malloc(255); 

由於strtok()雕刻了原來command數組,你不必與malloc()分配額外的空間;您可以簡單地將parameter[n]指針指向原始命令字符串的相關部分。然而,一旦你超越空間分隔的命令(在真實的shell中,|符號不必被空格包圍,但它在你的空間中),那麼你可能需要複製命令字符串的各個部分,所以這不是完全錯誤的。

您應該檢查內存分配是否成功。

cp = strtok(command, " ");      //Get the initial string (the command) 
strncpy(parameter[0], cp, 50); 

您分配了255個字符;您最多可以複製49個。最好等到您將參數隔離後再複製 - 只分配所需的空間。請注意,如果(指向該路徑的)命令名稱的長度等於或大於50個字符,則不會有以空字符結尾的字符串 - 由malloc()分配的空間不會歸零,並且strncpy()不會在超長字符串上寫入尾隨零。

for (i = 1; i < MAX_ARG; i++) 

目前尚不清楚您應該對參數的數量有一個上限,就像這樣簡單。有一個上限,但它通常在所有參數的總長度上。

{ 
    parameter[i] = malloc(255); 

關於內存分配和檢查的相似評論。

cp = strtok(NULL, " "); 
    parameter[i] = cp; 

哎呀!有記憶。對於泄漏抱歉。

if (strcmp(parameter[i], "|") == 0) 

我認爲複製前做比較可能會更好...另外,你不希望管道在任何一個命令的參數列表中;它是shell的符號,不是命令參數列表的一部分。你還應該確保第一個命令的參數列表以NULL指針終止,特別是因爲i設置在MAX_ARG的下面,所以你不知道指定了多少個參數。

{ 
     i = MAX_ARG; 
     cp = strtok(NULL, " "); 
     parameter2[0] = malloc(255); 
     strncpy(parameter2[0], cp, 50); 

這感覺很奇怪;您隔離該命令,然後分別處理其參數。設置i = MAX_ARG似乎很有趣,因爲你的下一個行動是打破循環。

 break; 
    } 
    if(parameter[i] == NULL) 
    { 
     break; 
    } 
} 

//Find the second set of commands and parameter 
//strncpy(parameter2[0], cp, 50); 
for (j = 1; j < MAX_ARG; j++) 
{ 
    parameter2[j] = malloc(255); 
    cp = strtok(NULL, " "); 
    parameter2[j] = cp; 
} 

如果您發現管道,您應該只能進入此循環。然後這段代碼像其他人一樣泄漏內存(所以你是一致的 - 一致性很重要;但是正確性也是如此)。

您需要檢查你的代碼,以確保它處理「無管道符號」得當,和「管,但沒有下面的命令」。在某些時候,你應該考慮多級流水線(三,四,...命令)。推廣你的代碼來處理這是可能的。

當寫猛砸代碼或等效的殼,我經常使用的符號,如這個劇本,這是我今天用了很多次。

ct find /vobs/somevob \ 
    -branch 'brtype(dev.branch)' \ 
    -version 'created_since(2011-10-11T00:00-00:00)' \ 
    -print | 
grep -v '/0$' | 
xargs ct des -fmt '%u %d %Vn %En\n' | 
grep '^jleffler ' | 
sort -k 4 | 
awk '{ printf "%-8s %s %-25s %s\n", $1, $2, $3, $4; }' 

它並沒有太大的關係(但它找到了我自10月11日以來在ClearCase的一個特定分支上所做的所有檢查)。這是我使用的符號很重要。 (是的,它可能會被優化 - 這是不值得的。)同樣,這不一定是你現在需要處理的 - 但它確實給你一個你需要去的地方。

+0

所以我改變了一點,但我的程序崩潰時,我比較cp和NULL, – user1003749

+0

我用一個新的代碼更新了我的原始問題 – user1003749