2016-11-24 66 views
0

我試圖製作一個程序,該程序使用exec調用lsgrep系統調用。具體而言,我必須執行ls > tmp; grep ­-c pattern < tmp以計算滿足該模式的文件數量。正如你所看到的,我將ls的內容保存在tmp文件中,然後我想用grep來計算這些文件。使用execl獲取grep值

我們來看看pattern = txt。我想要的東西,如下面的代碼:

char *a = "ls > tmp"; 
char *b = " -c "; 
char *fin = " < tmp"; 
char *comanda; 
if((comanda = malloc(strlen(pattern)+strlen(pattern)+1)) != NULL){ 
    comanda[0] = '\0'; // ensures the memory is an empty string 
    strcat(comanda,b); 
    strcat(comanda, pattern); 
    strcat(comanda,fin); 
} else { 
    return -1; 
} 

ret = execl("/bin/sh","sh","-c",a,NULL); 
ret = execl("/bin/sh","sh","-c",comanda, NULL); 

但它讓我看到以下錯誤:ls: cannot access > tmp: No such file or directory。所以我不知道如何得到grep的值,因爲execl函數沒有返回值,所以我怎樣才能達到grep的值呢?

+0

您需要在()'和'叉創建一個子進程運行'execl'。 'execl()'用你運行的程序替換當前進程,它只會在嘗試加載程序時出錯。 – Barmar

+0

這是我的實際觀點,在一個子進程中,我將使用'execl',但無論如何,我得到的錯誤是:'ls:無法訪問> tmp:沒有這樣的文件或目錄' –

+0

我不能再現那個錯誤,除非我改變它到'char * a =「ls'> tmp'」;' – Barmar

回答

1

要獲得命令的輸出,您需要使用管道。

看一看:Connecting n commands with pipes in a shell?

你可能只是做:

ls | grep -c pattern 

如果你只是想獲得與文件名的特定模式的文件,你可能想使用find

find your_path/ -name "*pattern*" | wc -l 

看看Grabbing output from exec得到execl的輸出

下面是一個例子,取代EXECL的任何你想要的:)

execl("/bin/sh", "sh", "-c", "ls > tmp; grep -c 'pattern' < tmp", (char *)NULL);)的第四個參數

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

int main() 
{ 
    int fd[2]; 
    pipe(fd); 

    if (fork() == 0) 
    { 
     close(fd[0]); 

     dup2(fd[1], 1); 
     dup2(fd[1], 2); 
     close(fd[1]); 

     execl("/bin/sh", "sh", "-c", "find your_path -name '*pattern*' | wc -l", (char *)NULL); 
    } 
    else 
    { 
     char buffer[1024] = {0}; 

     close(fd[1]); 

     while (read(fd[0], buffer, sizeof(buffer)) != 0) 
     { 
     write(1, buffer, strlen(buffer)); 
     memset (buffer, 0, sizeof(buffer)); 
     } 
    } 
    return 0; 
} 
+0

您能給我舉個例子嗎? –

+0

問題是我必須使用'ls> tmp; grep -c pattern

+0

好吧,如果你不需要使用'execl',那麼使用'system'來讓你有重定向。否則,玩'fork'和'dup2'。 –

0

你不分配正確的空間量comanda,因爲你不」 t正確添加所有變量的大小。所以如果大小太小,當你完成所有的strcat時,你會寫入數組邊界之外,這會導致未定義的行爲。

你不需要臨時文件,你可以從ls管道grep。如果它包含特殊字符,我還在模式中添加了引號。

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

int main() { 
    char *a = "ls | grep -c '"; 
    char *fin = "'"; 
    char *pattern = "foo"; 
    char *comanda; 
    if((comanda = malloc(strlen(a) + strlen(pattern) + strlen(fin) +1)) != NULL){ 
     strcpy(comanda,a); 
     strcat(comanda,pattern); 
     strcat(comanda,fin); 
    } else { 
     return -1; 
    } 
    int ret = execl("/bin/sh","sh","-c", comanda, (char*)NULL); 
    perror("execl"); // Can only get here if there's an error 
}