使用execl获取grep值

时间:2016-11-24 13:42:47

标签: c linux bash shell grep

我正在尝试使用ls创建一个调用grepexec系统调用的程序。具体来说,我必须执行ls > tmp; grep ­-c pattern < tmp才能计算满足该模式的文件数。正如您所看到的,我将ls的内容保存在tmp文件中,然后我想使用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值?

2 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:0)

您没有为comanda分配正确的空间量,因为您没有正确添加所有变量的大小。因此,如果大小太小,当您执行所有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
}