【问题标题】:Get grep value using execl使用 execl 获取 grep 值
【发布时间】:2017-04-08 20:24:30
【问题描述】:

我正在尝试制作一个使用exec 调用lsgrep 系统调用的程序。具体来说,我必须执行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 &gt; tmp: No such file or directory。所以我不知道如何获取grep的值,因为execl函数没有返回值,那么如何实现grep的值呢?

【问题讨论】:

  • 您需要在使用fork() 创建的子进程中运行execlexecl() 将当前进程替换为您运行的程序,只有在尝试加载程序时出错时才会返回。
  • 这是我的实际观点,在子进程中我将使用execl,但无论如何我都会遇到同样的错误:ls: cannot access &gt; tmp: No such file or directory
  • 除非我将其更改为 char *a = "ls '&gt; tmp'";,否则我无法重现该错误
  • 你能告诉我你的代码吗?

标签: c linux bash shell grep


【解决方案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 &gt; tmp; grep -c 'pattern' &lt; 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;
}

【讨论】:

  • 问题是我必须使用ls &gt; tmp; grep ­-c pattern &lt; tmp 作为要求。所以我会看看管道。
  • 好吧,如果您不必使用execl,请使用system,它可以让您进行重定向。否则,请使用 forkdup2
  • 我不能使用system,这也是另一个要求。
  • 他没有将&gt; 作为参数传递,而是调用/bin/sh 并传递一个包含重定向的命令行。为什么shell不解析命令?
  • 是的,你在写,我一开始没有注意 sh -c。
【解决方案2】:

您没有为comanda 分配正确的空间量,因为您没有正确添加所有变量的大小。所以如果大小太小,当你执行所有strcat 时,你会在数组边界之外写入,这将导致未定义的行为。

你不需要临时文件,你可以从lsgrep。我还在模式周围添加了引号,以防它包含特殊字符。

#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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-13
    • 2016-09-24
    • 2022-01-25
    相关资源
    最近更新 更多