2016-12-17 11 views
-1

私は奇妙な問題が発生しています。宿題のために私は自分の基本的なbashスクリプトを作成していますが、execv()を実行してcpコマンドを実行すると動作しません。これはlsとグループでは動作しますが、cpでは動作しません。私はエラーを分離するために自分のcpプログラムを使いこなしました。それは確かにexecvコマンドです。execv()が正しく動作しない

void ls(char** array) 
{ 
     pid_t pid = fork(); 
     if (pid == 0) 
     { 
       execv("./ls",array); 
     } 
     else 
     {  
       waitpid(pid,0,0); 
     } 

} 

void cp(char** array) 
{ 
     pid_t pid = fork(); 
     if (pid == 0) 
     { 
       execv("./cp",array); 
     } 
     else 
     { 
       waitpid(pid,0,0); 
     } 
} 

void groups(char** array) 
{ 
     pid_t pid = fork(); 
     if (pid == 0) 
     { 
       execv("./groups",array); 
     } 
     else 
     { 
       waitpid(pid,0,0); 
     } 
} 

int input() 
{ 
     char buffer[128]; 
     char * str; 
     char * str1; 
     char * str2; 
     char * str3; 
     char *name; 
     int i = 0; 
     int num; 
     int words = 1; 
     name = getlogin(); 
     printf("%s --->", name); 
     int result = scanf("%[^\n]",buffer); 
     getchar(); 
     char **array; 
     if (result > 0) 
     { 
       for (int i = 0; buffer[i]!='\0'; i++) 
       { 
         if (buffer[i] == ' ' || buffer[i] == '\n' || buffer[i] == '\t') 
         { 
           words++; 
         } 
       } 

       array = malloc(words * sizeof(char*)); 
       array[0] = strtok(buffer, " "); 
       for(int w = 1; w < words; w++) 
       { 
         array[w] = strtok(NULL, " "); 
       } 
       if (words == 1) 
       { 
         array[1] = '\0'; 
       } 

     } 
     str = strstr(array[0], "ls"); 
     str1 = strstr(array[0], "cp"); 
     str2 = strstr(array[0], "groups"); 
     str3 = strstr(array[0], "exit"); 
     if (str != NULL) 
     { 
       ls(array); 
       free(array); 
     } 
     else if (str1 != NULL) 
{ 
       cp(array); 
       free(array); 
     } 
     else if (str2 != NULL) 
     { 
       groups(array); 
       free(array); 
     } 
     else if (str3 != NULL) 
     { 
       num = 0; 
       free(array); 
       return num; 
     } 
     else 
     { 
       printf("Incorrect command\n"); 
     } 
     num = 1; 
     return num; 

このスニペットはうまくいくはずです。私のコードはexecvに正しく到達しますが、それは何らかの理由で実行されません。 lsとgroupsは正常に動作しますが、cpは動作しません。私の主な呼び出しは入力

+2

あなたは、いくつかのデバッグ出力、エラーチェックを追加したことがありますか? 'array'には何がありますか? 「うまくいかない」とはどういう意味ですか? – pvg

+0

'cp'が現在の作業ディレクトリにあることを確認しました –

+0

はい、私は正しいディレクトリにあります。動作しないと、私はcpコマンドが呼び出されたときに何も表示しないことを意味します。基本的に、ユーザはcp [file] [destination]と入力します。私がenterを押すと、何もしません。 execvが-1を返すと、正しく実行されなかったことを示します。 –

答えて

3

制限された情報に基づいて推測すると、パラメータとして送信される配列には、cpに送信する2つのものの1つだけが含まれています。 execvを呼び出す前に、配列を印刷して、送信元と宛先の両方をcpに送信することを確認してください。配列の最後の要素がヌルポインタであることも確認してください。

+0

ソースと宛先が正しく取得されています。私も自分のcpプログラムに入り、最初の行に文を印刷していましたが、それはしませんでした。 –

+1

配列の最後の要素としてヌルポインタがあることを確認します。 –

+0

これは興味深いことですが、そうしようとするとセグメント化エラーが発生します –

2

これは私の作品:

char* args[] = { "/bin/cp", "/etc/passwd", "passwd-copy", 0 }; 
pid_t pid; 
if(0>(pid=fork())){ 
    perror(0); 
    return -1; 
} 
if(0==pid){ 
    execv(args[0], args); 
    perror(0); 
    _exit(127); 
} 
siginfo_t info; 
if(0>waitid(P_PID, pid, &info, WEXITED)){ 
    perror(0); 
    return -1; 
} 
return info.si_status; 
+0

はNULLではありません(ただし、Cの暗黙の変換機能がプログラムを保存する可能性があります)。関数 'perror()'はポインタをパラメータであり、整数ではありません。配列 'args {} 'は最後のエントリを0ではなくNULLにする必要があります。 – user3629249

+0

@ user3629249実際に' 0'は 'NULL'マクロの完全準拠の値です。'(void *)0'です。時には 'execlp(" foo "、" foo "、" bar "、(char *)0);のようなキャストが必要ですが、上記の文脈では(' stdio.h'が含まれていれば) 'perror'のプロトタイプがそれに伴ってもたらされます)。 – PSkocik

+0

@ user3629249 'perror(0)'はsemを 'perror(" ")'として扱います - 接頭辞なし、コロンなし、単に文字列化された 'errno'。私は 'perror'にヌルポインタを許すことは悪い設計(perror'関数全体である)ですが、それが利用可能で、人々がそれを使用しているので、私もそうかもしれません。 – PSkocik