自定义 shell glob 问题

发布于 2024-11-27 21:37:18 字数 947 浏览 1 评论 0原文

我必须用 c 编写一个 shell 程序,不使用 system() 函数。其中一个功能是我们必须能够使用通配符。我似乎找不到一个很好的例子来说明如何使用 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 如何工作的人都知道可能的原因是什么?如果需要的话可以发布更多代码,但这就是问题所在。

I have to write a shell program in c that doesn't use the system() function. One of the features is that we have to be able to use wild cards. I can't seem to find a good example of how to use glob or this fnmatch functions that I have been running into so I have been messing around and so far I have a some what working blog feature (depending on how I have arranged my code).

If I have a glob variable declared as a global then the function partially works. However any command afterwards produces in error. example:

ls *.c
produce correct results
ls -l //no glob required
null passed through

so I tried making it a local variable. This is my code right now:

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;

}

When doing this with the globbuf as a local, it produces a null for globbuf.gl_path[0]. Can't seem to figure out why. Anyone with a knowledge of how glob works know what might be the cause? Can post more code if necessary but this is where the problem lies.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

酒浓于脸红 2024-12-04 21:37:18

这对我有用:

...
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 是最简单的> 复制 glob_buffer.gl_pathv[] 中的所有元素并在末尾添加 NULL 指针。

this works for me:

...
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 );
...

Observe that the execvp function expects the argument list to end with a NULL pointer, i.e. I think it will be the easiest to create your own char ** argv copy with all the elements from the glob_buffer.gl_pathv[] and a NULL pointer at the end.

骄傲 2024-12-04 21:37:18

您正在请求 GLOB_DOOFFS,但您没有在 globbuf.gl_offs 中指定任何数字来说明要保留多少个插槽。

据推测,作为全局变量,它被初始化为 0。

此外,&globbuf.gl_pathv[0] 可以简单地为 globbuf.gl_pathv

并且不要忘记运行globfree(globbuf)

我建议在 valgrind 下运行您的程序,因为它可能存在大量内存泄漏和/或访问未初始化的内存。

You are asking for GLOB_DOOFFS but you did not specify any number in globbuf.gl_offs saying how many slots to reserve.

Presumably as a global variable it gets initialized to 0.

Also this: &globbuf.gl_pathv[0] can simply be globbuf.gl_pathv.

And don't forget to run globfree(globbuf).

I suggest running your program under valgrind because it probably has a number of memory leaks, and/or access to uninitialized memory.

小梨窩很甜 2024-12-04 21:37:18

如果您不必使用 * 样式通配符,我总是发现使用 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
  }
}

记住要 closedir() 你 opendir() 一样。如果您想使用 struct dirent,则它具有 d_type 字段,大多数文件都是 DT_REG 类型(不是目录、管道、符号链接、套接字等)。

它不会像 glob 那样创建列表,目录就是列表,您只需使用条件来控制从中选择的内容。

If you don't have to use * style wildcards I've always found it simpler to use opendir(), readdir() and strcasestr(). opendir() opens a directory (can be ".") like a file, readdir() reads an entry from it, returns NULL at the end. So use it like

struct dirent *de = NULL;
DIR *dirp = opendir(".");
while ((de = readdir(dirp)) != NULL) {
  if ((strcasestr(de->d_name,".jpg") != NULL) {
  // do something with your JPEG
  }
}

Just remember to closedir() what you opendir(). A struct dirent has the d_type field if you want to use it, most files are type DT_REG (not dirs, pipes, symlinks, sockets, etc.).

It doesn't make a list like glob does, the directory is the list, you just use criteria to control what you select from it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文