我必须在c中编写一个不使用system()函数的shell程序。其中一个功能是我们必须能够使用外卡。我似乎无法找到一个很好的例子,说明如何使用glob或我遇到的这个fnmatch函数,所以我一直在搞乱,到目前为止我有一些工作博客功能(取决于我如何安排我的码)。
如果我将glob变量声明为全局变量,那么函数部分工作。但是之后的任何命令都会产生错误。例:
ls *.c
produce correct results
ls -l //no glob required
null passed through
所以我试着把它变成局部变量。这是我现在的代码:
int runCommand(commandStruct * command1) {
if(!globbing)
execvp(command1->cmd_path, command1->argv);
else{
glob_t globbuf;
printf("globChar: %s\n", globChar);
glob(globChar, GLOB_DOOFFS, NULL, &globbuf);
//printf("globbuf.gl_pathv[0]: %s\n", &globbuf.gl_pathv[0]);
execvp(command1->cmd_path, &globbuf.gl_pathv[0]);
//globfree(&globbuf);
globbing = 0;
}
return 1;
}
当使用globbuf作为本地执行此操作时,它会为globbuf.gl_path [0]生成null。似乎无法弄清楚为什么。任何了解glob工作原理的人都知道原因可能是什么?可以在必要时发布更多代码,但这就是问题所在。
这对我有用:
...
glob_t glob_buffer;
const char * pattern = "/tmp/*";
int i;
int match_count;
glob( pattern , 0 , NULL , &glob_buffer );
match_count = glob_buffer.gl_pathc;
printf("Number of mathces: %d \n", match_count);
for (i=0; i < match_count; i++)
printf("match[%d] = %s \n",i,glob_buffer.gl_pathv[i]);
globfree( &glob_buffer );
...
观察到execvp
函数期望参数列表以NULL指针结束,即我认为使用char ** argv
中的所有元素和末尾的NULL指针创建自己的glob_buffer.gl_pathv[]
副本是最简单的。
你要求GLOB_DOOFFS
,但你没有在globbuf.gl_offs
中指定任何数字,说明要保留多少个插槽。
大概作为一个全局变量,它被初始化为0。
这也是:&globbuf.gl_pathv[0]
可以简单地是globbuf.gl_pathv
。
并且不要忘记运行globfree(globbuf)
。
我建议在valgrind
下运行你的程序,因为它可能有许多内存泄漏,和/或访问未初始化的内存。
如果你不必使用* style通配符,我总是发现使用opendir(),readdir()和strcasestr()更简单。 opendir()像文件一样打开一个目录(可以是“。”),readdir()从中读取一个条目,最后返回NULL。所以就像使用它一样
struct dirent *de = NULL;
DIR *dirp = opendir(".");
while ((de = readdir(dirp)) != NULL) {
if ((strcasestr(de->d_name,".jpg") != NULL) {
// do something with your JPEG
}
}
只记得关闭()你的opendir()。如果你想使用它,struct dirent有d_type字段,大多数文件是DT_REG类型(不是dirs,管道,符号链接,套接字等)。
它没有像glob这样的列表,目录是列表,你只需使用条件来控制你从中选择的内容。