execvp找到wildcard -name" * .c"

时间:2018-06-01 06:46:42

标签: c wildcard execvp

如何使用" *。c"运行execvp。我可以使用全名而不是通配符。任何帮助将不胜感激。这就是我到目前为止所拥有的。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(void) {
    printf("running\n");    
    char* args[] = { "find", "-name", "one.c",  NULL};
    char * envp[] ={NULL};

    int pid = fork();

    switch(pid){
        case -1:
            perror("fork() failed");
            exit(1); 
        case 0: // child
            execvp(args[0], args);
            printf("after the exec\n"); 
        default: // parent 
            //wait(NULL);
            if(wait(NULL) == -1){
                perror("wait() failed"); 
            }
    }

    return 0; 
}

2 个答案:

答案 0 :(得分:0)

这是按设计。通配符处理可能很昂贵,因为它需要浏览文件夹。默认情况下,它通常在shell中处于活动状态,但在API函数中则不存在。一个值得注意的例外是system,因为它实际上将命令传递给shell:

  

system()函数将参数字符串交给命令inter-        preter sh(1)

exec...族函数不这样做,并假设路径是真实路径,并且不对通配符进行特殊处理。简单地说,exec[lv]p从PATH环境变量获取所有文件夹,并尝试在其中一个文件中找到一个名为的文件

您必须使用glob函数进行通配符处理。顺便说一句,shell程序使用它......

答案 1 :(得分:0)

您必须进行自己的通配符扩展。当您使用exec()系列函数时,您几乎直接将参数传递给新程序。

如果你想让替换程序为你替换通配符,你可能希望使用shell来做(如system()那样),但要小心,因为你需要正确引用对于壳。

示例:

char shell[] = "/bin/sh\0-c\0ls *.c";
char *args[] = { shell, shell+8, shell + 11, 0 };

execv("ls", args);

另请注意,字符串文字为const char*,因此不应使用char*[]填充。

但是,如果是find,您可能不想想要扩展通配符。在这里,没有必要做任何特别的事情 - 只需将*.c作为其中一个参数。 find命令(特别是-name参数)需要模式,而不是文件名列表,因此无法进行扩展:

char shell[] = "/usr/bin/find\0.\0-name\0*.c";
char *args[] = { shell, shell+14, shell + 16, shell+22, 0 };

execv("find", args);