2013-05-30 148 views
-1

我編寫了一個基本的shell,我的第一個要求是測試cd,我有我所有的可能的cd命令的條件,之後,我會交出像ls這樣的命令。至於現在我對一塊代碼感到困惑。爲什麼chdir()不成功?

#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <stdlib.h> 

#define MAX_TOK 50 
#define MAX_LEN 100 
#define BUFSIZE 81 

int tokenize(char *cmd, char tokens[MAX_TOK][MAX_LEN]){ 
    char *token; 
    int NUM_TOKENS = 0; 
    //printf("Splitting the string \"%s\" into tokens:\n",cmd); 
    token = strtok(cmd, " "); 

    while(token != NULL){ 
     strcpy(tokens[NUM_TOKENS],token); 
     token = strtok(NULL, " "); 
     NUM_TOKENS++; 
    } 
     return NUM_TOKENS; 
    } 

void decide(char tokens[MAX_TOK][MAX_LEN], int NUM_TOKENS){ 

    char *home = getenv("HOME"); 
    int success; 
    char *cd = {"cd"}; 
    char *string = tokens[1]; 
    //printf("Number of tokens %d\n", NUM_TOKENS); 
    //printf("%d\n",strcmp(tokens[0], cd)); 

    if(strcmp(tokens[0], cd) == 0){ 
     if(NUM_TOKENS > 2){ 
      printf("error: Too many arguments\n"); 
     } 
     else{ 
      printf("Changing to new directory %s \n",tokens[1]); 
      char *string = tokens[0]; 
      //printf("%s\n", tokens[1]); 
      success = chdir(tokens[1]); 
      printf("%d\n",success); 
     } 
    } 
    else{ 
     printf("Completing the %s request\n",tokens[0]); 
     take_action(tokens[0]); 
    } 
} 

void take_action(char *cmd){ 
    printf("%s\n",cmd); 
    int len; 
    int return_code; 
    char buffer[BUFSIZE]; 
    int pid; 
    pid = fork(); 
    if(pid != 0){ 
     //parent process executing 
     wait(NULL); 
    }else{ 
     //child process executing 
     len = strlen(buffer); 
     if(buffer[len-1] == '\n'){ 
     buffer[len-1] = '\0'; 
     } 
    return_code = execlp(cmd, cmd, NULL); 
    if(return_code != 0){ 
     printf("Error executing %s.\n", cmd); 
    } 
    }//end else 
} 

int main(){ 
char *cmd; 
char tokens[MAX_TOK][MAX_LEN]; 
int len; 
int return_code; 
char buffer[BUFSIZE]; 
int pid; 

while(cmd != NULL){ 
    printf("Enter a command\n"); 
    cmd = fgets(buffer, BUFSIZE, stdin); 
    // find the command 
    int NUM_TOKENS = tokenize(cmd, tokens); 
    //print_tokens(NUM_TOKENS, tokens); 
    decide(tokens,NUM_TOKENS); 
} 



}//end main 

當硬編碼chdir("test")代碼運行正常,如果在命令行上的用戶進入"cd test"tokens[0]cdtokens[1]是字符串"test"chdir(tokens[1])失敗,我不明白爲什麼。

打印標記[1]還顯示「test」爲存儲的字符串。當傳遞一個參數給take_action的時候,我被告知發生衝突的類型。在這兩個打印語句中都顯示了正確的字符串。據我所知,沒有額外的空間,因爲我的tokentize函數將它們全部剝離。我很困惑,這兩個部分看起來很簡單,但不會工作。

+4

如果'chdir()'失敗,它設置'errno',所以它應該告訴你爲什麼失敗。你可能會發現打印'string'也很有幫助,所以你可以清楚地看到 – Mike

+0

@ user2045236中傳遞的是什麼,如果你沒有做錯,'chdir(「test」)'很好,但是在命令提示符下你沒有顯式地只需'''',只要'ch test'沒問題...在'chdir()'調用之前打印'token [i]'並且懷疑它打印的是什麼 –

+0

@GrijeshChauhan當我打印出令牌[1 ]在行printf(「%s \ n」,令牌[1]);輸出是test。 – user2045236

回答

3

用戶不輸入cd test。他輸入cd test,然後點擊Enter鍵。

這意味着你將有:

token[0] = "cd"; 
token[1] = "test\n"; 

而且你沒有一個名爲"test\n",這將是"test"。您需要剝離最後一個標記中的換行符。

例如改變主要做

char *tmp; 
cmd = fgets(buffer, BUFSIZE, stdin); 
if (cmd && (tmp = strrchr(buffer, '\n')) != NULL) { 
    *tmp = 0; 
} 
+0

你是認真的嗎?回車鍵添加一個\ n字符?一個人如何剝奪這個角色? – user2045236

+1

@ user2045236它當然可以。在某些系統上,它會添加'\ r \ n' – nos

+0

我不明白爲什麼這樣做(我的大學說我只需要教我java就需要這門課程),但它確實!我將在man頁面中查找strrchr!非常感謝你! – user2045236

3

代碼

char *string = tokens[0]; 
printf("%s\n", tokens[1]); 
success = chdir(string); 

將轉化爲

success = chdir("cd"); 

我想你想

char *string = tokens[1]; 
//     ^

代替。

+0

Simonc我認爲你們的答案都是正確的,但OP也說'chdir(令牌[1])失敗......「據我的理解,這意味着你的答案不正確。我錯了嗎?或誤解了什麼? –

+0

這是我錯過的錯誤,但即使進行了更正,chdir()也會返回-1,這意味着它無法更改目錄。我不知道爲什麼。 – user2045236

+0

Grijesh Chauhan你是正確的,既不使用指向字符串的指針,也不使用存儲的標記值。這就是我困惑的原因。 – user2045236

1

token[0]cdtoken[1]path。所以使用char* string=token[1]

+0

你是不是指'string = token [1]'?你所沒有的就是問題中已經存在的內容。 – Mike

+0

@Mike代表akhil糾正,我也覺得他想寫''[1]' –