execvp 查找通配符 -name "*.c"

execvp find wildcard -name "*.c"

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

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

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

The system() function hands the argument string to the command inter- preter sh(1)

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

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

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

如果您希望替换程序为您替换通配符,您可能希望使用 shell 来做到这一点(就像 system() 那样),但要小心,因为您会需要正确引用 shell.

示例:

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

execv("ls", args);

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


但是,在 find 的情况下,您可能 不想 扩展通配符。在这里,不需要做任何特别的事情 - 只需将 *.c 作为参数之一传递即可。 find 命令(特别是 -name 参数)需要一个 模式 ,而不是文件名列表,因此没有扩展可做:

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

execv("find", args);