【问题标题】:How to support wildcard word expansion in my own shell implementation?如何在我自己的 shell 实现中支持通配符扩展?
【发布时间】:2021-02-12 14:57:44
【问题描述】:

我正在编写自己的一个非常简单的 shell 的实现,但我想支持通配符扩展。我在 stackoverflow 上阅读了一个答案,该答案建议在对命令进行标记时使用 glob(3) 进行单词扩展。

一个使用示例是下面的代码,它模拟打字

ls -l *.c ../*.c

在外壳中:

glob_t globbuf;

globbuf.gl_offs = 2;
glob("*.c", GLOB_DOOFFS, NULL, &globbuf);
glob("../*.c", GLOB_DOOFFS | GLOB_APPEND, NULL, &globbuf);
globbuf.gl_pathv[0] = "ls";
globbuf.gl_pathv[1] = "-l";
execvp("ls", &globbuf.gl_pathv[0]);

知道如何使这个动态化并使用没有通配符的命令以及只有一个或多个通配符的命令吗?

glob(3) 是支持 shell 通配符扩展的最佳方式还是有更好的方式? 正则表达式会是更好的选择吗?我正在尝试在这里学习,如果我误解了某些内容,请原谅我,因为我是该领域的初学者。

这是我的标记器,以防万一:

int build_args(char * cmd, char ** argv) {
char *token; 
token = strtok(cmd," ");
int i=0;
while(token!=NULL){
    argv[i]=token; 
    token = strtok(NULL," "); 
    i++; 
}
    argv[i]=NULL; 
    return i; 
}

【问题讨论】:

    标签: c shell wildcard glob


    【解决方案1】:

    我的专家意见:glob(3) 不是最好的方法,但它是最简单的方法。如果您要编写一个全新的 shell,那么也许它应该具有一些其他 shell 不具备的功能 - 否则,为什么不编写一个 shell,它可能有一些 glob 不支持的额外通配符。那你就不能用glob了。

    Unix shell 的工作方式是您可以在任何命令行中始终 glob,它不依赖于命令。因此,您甚至可以这样做:

    % touch echo Hello world
    % ls
    echo  hello  world
    % *
    hello world
    

    即glob 运算符扩展为 echo hello world,这是随后运行的命令。

    但是,如果将通配符括在例如引号。

    【讨论】:

    • 感谢您的指导,但是您能指导我如何使用 glob(3) 进行通配符匹配和扩展吗?我选择它是因为它是最简单的,我不想添加更多其他 shell 中没有的功能,我只是想通过自己构建它们来了解它们在内部是如何工作的。
    【解决方案2】:

    阅读glob(7) - 一个有趣的规范。另请阅读syscalls(2)。在某些现有 shell process 上使用strace(1)ltrace(1)(了解该shell 在您运行它时实际做了什么,以及system calls 当您您时shell 在做什么 运行它)。

    您可以使用glob(3)(但请参阅fnmatch(3)nftw(3)...)。你也可以使用opendir(3) + readdir(3) + stat(2) + closedir(3)

    最后,GNU bashfree software。为什么不下载并研究它的源代码呢?或查看sash 的代码或zsh 的代码内部...。两者都是open source

    【讨论】:

    • strace 有什么帮助?
    • 系统调用(2)中有什么相关的?
    • Shell 正在使用系统调用。
    • 一切都使用系统调用。有什么特别相关的?
    • 我建议研究现有 shells的源代码
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-12
    • 2010-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多