2014-03-05 82 views
0

我正在做一個代碼,它將執行Linux命令管道。基本上在我的代碼中,它將解析用戶輸入命令,然後使用execvp函數運行它。爲什麼我的C++數組打印相同的值?

但是,要做到這一點,我需要知道命令以及它的參數。我一直試圖讓解析工作正常,但是,似乎當我做一個測試用例時,來自兩個存儲它們各自程序的數組的輸出是相同的。命令/參數存儲在名爲prgname1prgname2的字符數組中。例如,如果我用參數「ps aux | grep [username]」運行我的程序,則prgname1 [0]和prgname2 [0]的輸出都是[用戶名]。它們分別應該是psgrep

任何人都可以看看我的代碼,看看我可能有哪個錯誤導致這個?

謝謝!

#include <sys/wait.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <iostream> 

#define MAX_PARA_NUM 5 
#define MAX_COMMAND_LEN 1024 

using namespace std; 

int main(int argc, char *argv[]) { 
char *prgname1[MAX_PARA_NUM], *prgname2[MAX_PARA_NUM]; 
char command[MAX_COMMAND_LEN]; 
int pfd[2]; 
pipe(pfd); 
pid_t cid1, cid2; 

char *full = argv[1]; 
char str[MAX_COMMAND_LEN]; 
int i = 0; 
int j = 0; 
int k = 0; 
int ind = 0; 
while (ind < strlen(full)) { 
    if (full[ind] == ' ') { 
     strncpy(command, str, i); 
     cout << command << endl; 
     prgname1[j] = command; 
     j++; 
     i = 0; 
     ind++; 
    } 
    else { 
     str[i] = full[ind]; 
     i++; 
     ind++; 
    } 

    if(full[ind] == '|') { 
     i = 0; 
     j = 0; 
     ind+=2; 
     while (ind < strlen(full)) { 
      if (full[ind] == ' ') { 
       strncpy(command, str, i); 
       cout << command << endl; 
       prgname2[j] = command; 
       j++; 
       i = 0; 
       ind++; 
      } 
      else { 
       str[i] = full[ind]; 
       i++; 
       ind++; 
      } 
      if (ind == strlen(full)) { 
       strncpy(command, str, i); 
       cout << command << endl; 
       prgname2[j] = command; 
       break; 
      } 
     } 
    } 
} 

    // test output here not working correctly 
cout << prgname1[0] << endl; 
cout << prgname2[0] << endl; 

// exits if no parameters passed 
if (argc != 2) { 
    cout << "Usage:" << argv[0] << endl; 
    exit(EXIT_FAILURE); 
} 

// exits if there is a pipe error 
if (pipe(pfd) == -1) { 
    cerr << "pipe" << endl; 
    exit(EXIT_FAILURE); 
} 
cid1 = fork(); // creates child process 1 

// exits if there is a fork error 
if (cid1 == -1 || cid2 == -1) { 
    cerr << "fork"; 
    exit(EXIT_FAILURE); 
} 
// 1st child process executes and writes to the pipe 
if (cid1 == 0) { 
    char **p = prgname1; 
    close(1); // closes stdout 
    dup(pfd[1]); // connects pipe output to stdout 
    close(pfd[0]); // closes pipe input as it is not needed 
    close(pfd[1]); // closes pipe output as pipe is connected  
    execvp(prgname1[0], p); 
    cerr << "execlp 1 failed" << endl; 
    cid2 = fork(); 
} 
// 2nd child process reads from the pipe and executes 
else if (cid2 == 0) { 
    char **p = prgname2; 
    close(0); // closes stdin 
    dup(pfd[0]); // connects pipe input to stdin 
    close(pfd[0]); // closes pipe input as pipe is connected 
    close(pfd[1]); // closes pipe output as it is not needed 
    execvp(prgname2[0], p); 
    cerr << "execlp 2 failed" << endl; 
} 
else { 
    sleep(1); 
    waitpid(cid1, NULL, 0); 
    waitpid(cid2, NULL, 0); 
    cout << "Program successfully completed" << endl; 
    exit(EXIT_SUCCESS); 
} 
return 0; 

}

回答

2

argv[1]讓你在命令行中的第一個參數 - 而不是整個命令行。如果您想要傳入進程的命令行參數的完整列表,則需要附加argv[1],argv[2],...,argv[argc - 1]以及每個之間的空格。

此外,當您處理它時,您將prgname1[index]的指針設置爲command,因此每次設置給定的字符指針時,它們都指向相同的位置(因此它們都是相同的值) 。您需要爲prgname1中的每個元素分配空間並將其複製command(使用strncpy)。或者,使用std::stringstd::vector可以消除大部分當前代碼。

相關問題