如何使用我写的一个可执行文件,同时浏览目录中的文件。

问题描述 投票:0回答:1

我写了一个可执行文件,用于检查是否存在以下组合 xattr tags. 我想在一个目录的所有文件上使用这个可执行文件,也就是说,我想在该目录中的所有文件上执行它,以及该目录中所有目录的文件......等等。

我的 xattr executable 和我用来递归导航的程序是这样的。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/xattr.h>
#include <string.h>
#include <errno.h>


int main(int argc, char const *argv[]){
    char argNormaux[4096] = {0};
    char argNeg[4096] = {0};
    char argEt[4096] = {0};
    int nbArgsNormaux = 0;

    if (argc > 2){
        for (int i = 2; i < argc; i++){
            const char *arg = argv[i];
            if (strstr(argv[i],"et") != NULL){
                // printf("%d. Et trouvé. Argument=%s\n", i, argv[i]);
                strcat(argEt, argv[i]);
            }
            else if (strstr(argv[i], "!") != NULL){
                // printf("%d. Négation trouvée. Argument=%s\n", i, argv[i]);
                strcat(argNeg, argv[i]);
            }
            else {
                // printf("%d. Argument trouvé=%s\n", i, argv[i]);
                strcat(argNormaux, argv[i]);
                nbArgsNormaux++;
            }
        }
        // printf("nbArgsNormaux=%d\n", nbArgsNormaux);
        // printf("Liste des arguments normaux: %s\n", argNormaux);
        // printf("Liste des négations: %s\n", argNeg);
        // printf("Liste des et: %s\n", argEt);

        const char *path = argv[1];
        printf("path=%s\n", path);
        // printf("Tags du fichier %s\n", path);
        char buf[4096];
        int rc;
        rc = listxattr(path, buf, sizeof(buf));
        if (rc < 0){
            perror("listxattr");
        }
        else {
            if (strlen(buf) == 0){
                printf("Il n'y a aucun tag sur ce fichier.\n");
                return 1;
            }
            int tagsNormauxCheck = 0;
            int tagsNegCheck = 0;
            char *token = buf;
            while(*token){
                char tagBuf[4096];
                if (strlen(token) == 2){
                    if (strcmp(token, "\0\0\0")) break;
                }
                rc = getxattr(path, token, &tagBuf, sizeof(tagBuf));
                if (rc < 0){
                    perror("getxattr");
                }
                else {
                    if (strstr(argNormaux, tagBuf) != NULL) {
                        // printf("tagbuf=%s\n", tagBuf);
                        // printf("Check NULL\n");
                        tagsNormauxCheck++;
                    }
                    if (strstr(argNeg, tagBuf) != NULL) {
                        tagsNegCheck = 1;
                        break;
                    }
                }
                memset(&tagBuf, 0, sizeof(tagBuf));
                token = strchr(token, '\0');
                token++;
            }
            // printf("Normaux=%d, NegCheck=%d\n", tagsNormauxCheck, tagsNegCheck);
            if (tagsNormauxCheck == nbArgsNormaux && tagsNegCheck == 0){
                printf("Le fichier %s possède la combinaison des tags donnés.", path);
                return 1;
            }
        }
    }
    else {
        printf("Pas assez d'arguments.\n");
        return 0;
    }
    return 0;
}
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#include <string.h>
#include <dirent.h>
#include <sys/types.h>
#include <unistd.h>

void listFilesRecursively(char *basePath, int argc, char const *argv[]){
    char path[4096];
    struct dirent *dp;
    DIR *dir = opendir(basePath);

    // Unable to open directory stream
    if (!dir) return;

    char const *cpArgv[argc+2];
    for (int i = 1; i < argc; i++){
        cpArgv[i] = argv[i];
    }
    cpArgv[argc+2] = NULL;
    while ((dp = readdir(dir)) != NULL){
        if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0){
            if (dp->d_type == DT_REG){
                cpArgv[0] = "./logic";
                cpArgv[1] = path;
                strcpy(cpArgv[1], basePath);
                strcat(cpArgv[1], "/");
                strcat(cpArgv[1], dp->d_name);
                printf("%s\n", dp->d_name);
                for (int i = 0; i < argc; i++){
                    printf("cpArgv[%d]=%s\n",i, cpArgv[i]);
                }

            }
            if (fork() == 0){
                execv("./logic",cpArgv);
            }
            // Construct new path from our base path
            strcpy(path, basePath);
            strcat(path, "/");
            strcat(path, dp->d_name);

            listFilesRecursively(path, argc, cpArgv);
        }
    }

    closedir(dir);
}

int main(int argc, char const *argv[]){
    if (argc > 1){
        listFilesRecursively(argv[1], argc, argv);
    }
    else {
        printf("Pas assez d'arguments, test.\n");
    }
    return 0;
}

这个 xattr program 单独使用时,从终端机完全可以正常工作。用来递归获取目录中所有文件的程序,在不使用下面的命令时也能完美地工作。forkexec. 然而,当我使用它们时,程序显示重复,xattr程序被执行,但没有找到标签,就像刚刚执行,但没有完成,一些文件没有显示......

这是我可以输出的一个例子。

dir2fichierUN.txt
cpArgv[0]=./logic
cpArgv[1]=testDir/dir2/dir2fichierUN.txt
cpArgv[2]=essai1
fichier1.txt
cpArgv[0]=./logic
cpArgv[1]=testDir/fichier1.txt
cpArgv[2]=essai1
fichier2.txt
cpArgv[0]=./logic
cpArgv[1]=testDir/fichier2.txt
cpArgv[2]=essai1
fichier1.txt
cpArgv[0]=./logic
cpArgv[1]=testDir/fichier1.txt
cpArgv[2]=essai1
fichier1.txt
fichier2.txt
cpArgv[0]=./logic
cpArgv[1]=testDir/fichier2.txt
cpArgv[2]=essai1
cpArgv[0]=./logic
cpArgv[1]=testDir/fichier1.txt
cpArgv[2]=essai1
fichier2.txt
cpArgv[0]=./logic
cpArgv[1]=testDir/fichier2.txt
cpArgv[2]=essai1
path=testDir/fichier1.txt
path=testDir/fichier2.txt
path=testDir/fichier1.txt
path=testDir/fichier2.txt
path=testDir/fichier1.txt
path=testDir/fichier2.txt
path=testDir/fichier1.txt
path=testDir/fichier2.txt

程序似乎在我的终端机上挂着...

我想在这里实现的是能够执行我的 xattr 在第一个目录下的每个文件上,第二个程序被调用。我的问题是,如何使它与 forkexecv.

你能帮我吗?

谢谢,我写了一个可执行文件。

c fork exec xattr
1个回答
1
投票

你不需要自己处理递归,你可以直接处理作为命令行参数的文件,然后使用 find 以递归方式将你的命令应用于层次结构中的所有文件。

find . -type f -exec logic args '{}' \;

如果你的 logic 程序无法从 $PATH 变量,将其名称替换为 find 参数列表。args 是你想在文件名之前传递给程序的参数。

© www.soinside.com 2019 - 2024. All rights reserved.