2016-09-16 32 views
1

我想做一個小殼。我的問題是,當我撥打execvp()時 - 我收到錯誤。 例如,當我輸入ls -l時,它返回ls: invalid option -- 'execvp()不能在我的shell中工作

有人能幫我理解爲什麼我得到這個錯誤嗎?對於我的代碼,函數命令split獲取用戶輸入,並將它們分解爲單獨的命令。單獨的命令由;字符分隔。

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

#define MAX_CHARACTERS 512 
#define HISTORY_SIZE 10 

int commandSplit(char *c, char *a[], int t[]) { 

int count = 0; 
int total = 0; 
char *temp[MAX_CHARACTERS]; 
char *readCommands = strtok(c, ";"); 
while(readCommands != NULL) { 
    printf("Reading full command: %s\n", readCommands); 
    temp[count] = readCommands; 
    count++; 
    readCommands = strtok(NULL, ";"); 
} 
printf("Done reading full commands\n"); 
for(int i = 0; i < count; i++) { 
    char *read = strtok(temp[i], " "); 
    int track = 0; 
    while(read != NULL) { 
     printf("Reading individual command: %s\n", read); 
     a[total] = read; 
     track++; 
     total++; 
     read = strtok(NULL, " "); 
    } 
    t[i] = track; 
} 

return count; 
} 

int main() { 

int exitProgram = 0; 
char *args[MAX_CHARACTERS]; 

while(!exitProgram) { 

char *commands = (char *)(malloc(MAX_CHARACTERS*sizeof(char))); 
int tracker[MAX_CHARACTERS]; 
int numOfCommands = 0; 
printf("tinyshell> "); 
fgets(commands, MAX_CHARACTERS, stdin); 

if(strlen(commands) == 0) continue; 

numOfCommands = commandSplit(commands, args, tracker); 
printf("There are %i commands!\n", numOfCommands); 

if(strcmp(args[0], "exit") == 0) { 
    printf("Exiting\n"); 
    exitProgram = 1; 
    continue; 
} 

int l = 0; 
for(int i = 0; i < numOfCommands; i++) { 
    int status; 
    char *holder[tracker[i]+1]; 
    for(int j = 0; j < tracker[i]; j++) { 
     holder[j] = args[l]; 
     printf("Assiging holder:%s\n", holder[j]); 
     l++; 
    } 
    holder[tracker[i]] = NULL; 
    printf("What is holder? \n"); 
    for(int o = 0; o < tracker[i]; o++) printf("%s", holder[o]); 
    pid_t p = fork(); 
    pid_t waiting; 
    if(p == 0) { 
    printf("I am in child process\n"); 
    execvp(holder[0], holder); 

    fprintf(stderr, "Child process could not execvp!\n"); 
    exit(1); 
    } 
    else { 
     if(p < 0) { 
      fprintf(stderr, "Fork FAILED!\n"); 
     } 
     else { 
      waiting = wait(&status); 
      printf("Child %d, status %d\n", waiting, status); 
     } 
    } 
    for(int i = 0; i < numOfCommands; i++) { 
     args[i] = NULL; 
    } 
} 

} 

return 0; 

} 
+0

確定'holder'正確端接?如果您在調試器中逐行執行代碼,它是否像您期望的那樣工作?你所期望的是所有的變量值嗎? –

+0

顯示'for(int o = 0; o

回答

2

您的問題是fgets()also reads the newline character。結果,execvp()自變量數組的最後一個參數包含一個換行符,導致ls抱怨無法識別的參數:您實際傳遞給ls的是-l\n;你需要通過的只是-l沒有換行符。

嘗試添加該代碼fgets電話後修剪輸入緩衝區:

int len; 
len = strlen(commands); 
if (len > 0 && commands[len-1] == '\n') { 
    commands[len-1] = '\0'; 
} 
+0

非常感謝。試圖弄清楚什麼是錯的,我瘋狂地開始瘋狂。 – David

+0

我似乎遇到了另一個問題。 當我輸入「ls -l; ls」時,它會同時執行兩個命令。但是,如果我輸入「ls; ls -l」它會正確執行第一個命令,但「ls -l」不會列出目錄,但它似乎也不會引發錯誤。我只是在我的屏幕上看到幾個空語句 – David

+2

@David嘗試使用調試器來跟蹤代碼並發現問題。 – kfx

相關問題