简体   繁体   中英

How to use exec or execv to run find command

I was using find . -name "file.txt" | tee -a file_path<.txt> find . -name "file.txt" | tee -a file_path<.txt> find . -name "file.txt" | tee -a file_path<.txt> to search for "file.txt" recursively starting on the current folder. The tee command was to save all the paths to the directories in which the "file.txt" was found. It worked just fine, but now I want to implement this command in C code.
Can you give me some help on how to implement it with system() , exec() , execv() , or any other function that you think is better or more approriate?

My point was to search for a file (file1.txt) and save all the paths that lead to it, in another file (file2.txt). Then:

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

I know how to use: fopen , fwrite , fread , opendir , but I cant manage to get the file paths, through the C code.

You probably don't need to run any process for that. You should probably use the nftw(3) function instead (it would be slightly faster, and don't need any external command like find ) to search for *.txt file in a file tree.

If you want to scan only one directory (not subdirectories) you could simply use opendir(3) & readdir(3) (don't forget the closedir ); you'll probably need to use something like snprintf(3) (or asprintf(3) ) to build the path.

BTW, there is also glob(3) & wordexp(3) (& stat(2) & access(2) ...) which might be relevant.

If you have some char* str; containing a path (eg indirectly given thru nftw ), you might test that it is ending with .txt with

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

If you insist on using an external find command consider popen(3) & pclose . Be afraid of code injection if the paths are coming externally as input (imagine a naughty user entering foo; rm -rf $HOME as a file name).

You should read Advanced Linux Programming ....

@BasileStarynkevitch has a good answer here.

However, if you want to do what you asked, you can use the system call to do it, as it passes its arguments to the shell, allowing you to do redirection etc.

Note, this is not in general a good idea because of the possibility of code injection, and because it's far more efficient to do it inside C using eg nftw() . However, for completeness, it's worth mentioning that it is possible .

This is an example of how to do it

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

Note : with this approach, when you call the processExample function the current working directory is the directory where the file lives, so you can use fopen() directly on filename .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM