如何使用exec或execv运行find命令

时间:2015-01-06 11:22:49

标签: c linux unix

我正在使用find . -name "file.txt" | tee -a file_path<.txt>来搜索&#34; file.txt&#34;以递归方式从当前文件夹开始。 tee命令用于保存所有路径到&#34; file.txt&#34;被找到。它工作得很好,但现在我想用C代码实现这个命令 您能否通过system()exec()execv()或您认为更好或更合适的任何其他功能为我提供一些帮助?

我的观点是在另一个文件(file2.txt)中搜索文件(file1.txt)并保存所有通向它的路径。然后:

open first file -> add/copy text -> close file -> 
open second file -> add/copy text...

我知道如何使用:fopenfwritefreadopendir,但我无法通过C代码获取文件路径。

3 个答案:

答案 0 :(得分:3)

您可能不需要为此运行任何流程。您应该使用nftw(3)函数(它会稍微快一点,并且不需要任何外部命令,如find)来搜索文件树中的*.txt文件。

如果您只想扫描一个目录(不是子目录),只需使用opendir(3)&amp; readdir(3)(不要忘记closedir);您可能需要使用类似snprintf(3)(或asprintf(3))的内容来构建路径。

顺便说一下,还有glob(3)&amp; wordexp(3)(&amp; stat(2)&amp; access(2) ...)可能相关。

如果您有一些char* str;包含路径(例如通过nftw间接给出),您可以测试它是以.txt结尾

int slen = strlen(str);
if (slen>4 && !strcmp(str-slen-4, ".txt")) {
  // do something when str ends with ".txt"
}

如果您坚持使用外部find命令,请考虑popen(3)&amp; pclose。如果路径来自外部作为输入,请害怕code injection(想象一个顽皮的用户输入foo; rm -rf $HOME作为文件名。)

您应该阅读Advanced Linux Programming ....

答案 1 :(得分:1)

@BasileStarynkevitch在这里有一个很好的答案。

但是,如果你想做你所要求的,你可以使用system调用来做,因为它将参数传递给shell,允许你进行重定向等。

注意,由于代码注入的可能性,这通常不是一个好主意,并且因为使用例如C语言在C中执行代码效率要高得多。 nftw()。但是,为了完整起见,值得一提的是

答案 2 :(得分:0)

这是如何做的一个例子

#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>

typedef void (*ProcessFileFunction)(const char *const);

void findFileByName(const char *const directory, const char *const filename, ProcessFileFunction process)
{
    DIR           *dir;
    struct dirent *entry;
    char           previousDirectory[PATH_MAX];

    dir = opendir(directory);
    if (dir == NULL)
        return;

    getcwd(previousDirectory, sizeof(previousDirectory));

    chdir(directory);
    while ((entry = readdir(dir)) != NULL)
    {
        struct stat statbuf;

        if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0))
            continue;
        if (stat(entry->d_name, &statbuf) == -1)
            continue;
        if (S_ISDIR(statbuf.st_mode) != 0)
            findFileByName(entry->d_name, filename, process);
        else if (strcmp(filename, entry->d_name) == 0)
            process(entry->d_name);
    }
    chdir(previousDirectory);

    closedir(dir);
}

void processExample(const char *const filename)
{
    printf("%s\n", filename);
}

int main()
{
    findFileByName(".", "file.txt", processExample);
    return 0;
}

注意:使用此方法,当您调用processExample函数时,当前工作目录是文件所在的目录,因此您可以直接在fopen()上使用filename {1}}。