2

这是我正在做的一组练习中的一个步骤。我编写的程序应该有两个以上的参数。第一个参数的使用尚未实现。其余参数是目录列表。

在这一步中,我要做的是为参数中给定的每个目录创建一个 cat 实例,使用 cat 获取每个目录的所有文件的内容并打印内容。我应该能够处理 /home/directory 和 /home/directory/ 之类的路径(最后一个 / 或没有)

目前我正在做的是尝试使用参数 /home/directory/* 运行 cat ,以便它读取给定目录中的所有文件并返回它们的内容。这是我的代码:

#include "Step1.h"

int main(int argc,char* argv[])
{
    if(argc < 3)
    {
        printf("Usage: ./Step1 <exclusions file> <folder1> <folder2> <folder3> ...\n");
        return -1;
    }

    int i;
    for(i=2; i<argc; i++)
    {
        int catpipe[2];
        if(pipe(catpipe))
        {
            printf("Error in pipe\n");
            return -1;
        }
        pid_t pid = fork();
        if(pid < 0)
        {
            printf("Error in fork\n");
            return -1;
        }
        if(!pid)
        {
            dup2(catpipe[1],1); // cat pipe is used to get the output of cat program into this program.
            close(catpipe[1]);
            close(catpipe[0]);
            char* args[3];
            args[0] = "/bin/cat";
            int length = strlen(argv[i]);
            char* path;
            if(argv[i][length - 1] != '/') // the path given does not have the ending / 
            {
                path = malloc(length + 3);
                strcpy(path,argv[i]);
                path[length] = '/';      //append / at the end
                path[length+1] = '*';    // append * at the end
                path[length+2] = '\0';
            }
            else
            {
                path = malloc(length + 2); // the path contains the ending /
                strcpy(path,argv[i]);
                path[length] = '*';        // append * at the end
                path[length+1] = '\0';
            }                 
            args[1] = path;
            args[2] = NULL;
            printf("%s\n",path);
            execvp("/bin/cat",args);
        }
        close(catpipe[1]);
        char buffer[200];
        int total = read(catpipe[0],buffer,200); // read the output of cat program and print it. 
        buffer[total]='\0';
        printf("The buffer contains: %s\n",buffer);
    }
    return 0;
}

我按如下方式运行此代码:

mod@mod-Inspiron-N5110:~/project$ ./Step1 exclusions ./testdirectory1 ./testdirectory2/

我得到的结果是:

/bin/cat: ./testdirectory1/*: No such file or directory
The buffer contains: 
The buffer contains: ./testdirectory2/*

mod@mod-Inspiron-N5110:~/project$ /bin/cat: ./testdirectory2/*: No such file or directory

mod@mod-Inspiron-N5110:~/project$

但是当我这样做时:

mod@mod-Inspiron-N5110:~/project$ /bin/cat ./testdirectory1/*

结果是:

Testline 1 of testfile1 in testdirectory1
Test line 1 of testfile1 in testdirectory1
Testline 1 of testfile2 in testdirectory1
Testline 1 of testfile3 in testdirectory1

请帮助我用我的程序得到这个结果。

提前致谢

4

2 回答 2

1

我想我找到了自己问题的答案。我发布这篇文章是因为相信有一天像我这样的人会发现它很有用。但是我还不太擅长C。因此,如果此答案是错误的,或者其中有一些错误/弱点,请随时纠正。

我的答案的关键是使用函数wordexp()。它可用于扩展给定路径:波浪号、正则表达式、变量等。所以这是我的答案:

#include "Step1.h"

int main(int argc,char* argv[])
{
    if(argc < 3)
    {
        printf("Usage: ./Step1 <exclusions file> <folder1> <folder2> <folder3> ...\n");
        return -1;
    }

    int i;
    for(i=2; i<argc; i++)
    {
        int catpipe[2];
        if(pipe(catpipe))
        {
            printf("Error in pipe\n");
            return -1;
        }
        pid_t pid = fork();
        if(pid < 0)
        {
            printf("Error in fork\n");
            return -1;
        }
        if(!pid)
        {
            dup2(catpipe[1],1); // cat pipe is used to get the output of cat program into this program.
            close(catpipe[1]);
            close(catpipe[0]);

            int length = strlen(argv[i]);
            char* path;
            if(argv[i][length - 1] != '/') // the path given does not have the ending / 
            {
                path = malloc(length + 3);
                strcpy(path,argv[i]);
                path[length] = '/';      //append / at the end
                path[length+1] = '*';    // append * at the end
                path[length+2] = '\0';
            }
            else
            {
                path = malloc(length + 2); // the path contains the ending /
                strcpy(path,argv[i]);
                path[length] = '*';        // append * at the end
                path[length+1] = '\0';
            }            

        wordexp_t p;
        char **w;
            wordexp(path, &p, 0);
        char** args = malloc((p.we_wordc + 2) * sizeof(char*));
            args[0] = "/bin/cat";   
        w = p.we_wordv;
        int j;
        for (j = 0; j < p.we_wordc; j++)
        args[j+1] = w[j];                
            args[p.we_wordc + 1] = NULL;

            execvp("/bin/cat",args);
        }
        close(catpipe[1]);
        char buffer[1024];
        int total = read(catpipe[0],buffer,1024); // read the output of cat program and print it. 
        buffer[total]='\0';
        printf("The buffer contains: %s\n",buffer);
    }
    return 0;
}
于 2014-01-28T15:51:19.720 回答
0

所以基本上你在代码中遇到的错误是你假设如果你/directory/*作为一个参数给cat,cat会将它扩展为“许多文件”,而cat理解你想要打开一个名为*.

进行扩展的简单方法*是通过 shell 调用 cat ,这将进行从*“许多文件”的扩展。

为此,您可以用调用替换 your execvp()system(…)这基本上execl("sh", "sh", "-c", …, NULL)就是您的命令所在的位置(即您可以简单地调用"/bin/sh", "-c", "/bin/cat", "/directory/*")并且*应该由 shell 扩展。

或者您可以使用自己的递归目录遍历算法,例如.

于 2014-01-26T14:39:32.727 回答