2016-11-24 65 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 
}