如何使用execv()在ls中传递额外选项?

use*_*165 0 c linux wildcard

我正在尝试ls -1 *.c使用execv()函数执行这个简单的命令.

#include<stdio.h>
#include<fcntl.h>
int main(int argc,char* argv[]){
char *arr[3]={"ls","-1","*.c"};
execv("/bin/ls",arr);
}
Run Code Online (Sandbox Code Playgroud)

我得到的输出是

ls: cannot access *.c: No such file or directory
Run Code Online (Sandbox Code Playgroud)

mel*_*ene 5

您的代码中存在一个大问题:execv无法判断您传递的数组有多大.你绝对需要一个终止NULL元素来标记结尾:

char *arr[] = { "ls", "-1", "*.c", NULL };
Run Code Online (Sandbox Code Playgroud)

好的,既然我们有一个有效的execv调用,我们可以处理ls错误.

这样调用execv等同于运行

'ls' '-1' '*.c'
Run Code Online (Sandbox Code Playgroud)

在命令行上(会产生相同的错误).

当你这样做

ls -1 *.c
Run Code Online (Sandbox Code Playgroud)

在命令行上,ls永远不会看到,*.c因为shell扩展了通配符并将匹配的文件名列表传递给ls.

如果要在C代码中复制它,则必须手动执行相同的操作.例如man glob,参见执行大部分工作的函数.以下是手册页中的一个改编示例,其中显示了一般原则:

glob_t globbuf;

globbuf.gl_offs = 2;
glob("*.c", GLOB_DOOFFS, NULL, &globbuf);
globbuf.gl_pathv[0] = "ls";
globbuf.gl_pathv[1] = "-1";
execv("/bin/ls", globbuf.gl_pathv);
Run Code Online (Sandbox Code Playgroud)