简体   繁体   English

shell 全局扩展如何像 ls -l * 一样工作?

[英]How shell glob expansion works as in ls -l *?

How is shell expanding the '*' as in shell 如何扩展“*”,如

ls -l * ls -l *

Is there any system calls happening behind the scene to read all the file in the directory?是否有任何系统调用在后台发生以读取目录中的所有文件? I tried strace but not showing any system calls specific to globbing我尝试了 strace 但没有显示任何特定于 globbing 的系统调用

The glob is expanded by bash, not by ls . glob 由 bash 扩展,而不是由ls扩展。 When you run strace ls * only the ls is traced, but the glob expands before ls or even strace runs so you won't see the system calls of it in the trace.当您运行strace ls *时,仅跟踪ls ,但 glob 在ls甚至strace运行之前扩展,因此您不会在跟踪中看到它的系统调用。

To trace the expansion of a glob use strace bash -c 'echo *' .要跟踪 glob 的扩展,请使用strace bash -c 'echo *' This will also include system calls from the shell startup.这还将包括来自 shell 启动的系统调用。 To show only the system calls done for echo * you can filter the results with...要仅显示为echo *完成的系统调用,您可以使用...过滤结果

strace bash -c '[ -e startglob ]; echo *; [ -e endglob ]' 2>&1 |
sed -n '/"startglob"/,/"endglob"/p'

Read glob(7) .阅读glob(7) Globbing would use several syscalls(2) : access(2) , stat(2) opendir(3) , readdir(3) (which uses getdents(2) ...) closedir(3) . Globbing 会使用几个系统调用(2)access(2)stat(2) opendir(3)readdir(3) (使用getdents(2) ...) closedir(3) See also nftw(3) .另见nftw(3)

And GNU bash is (like GNU libc and the Linux kernel ) free software , you can download its source code and study it, compile it and improve it.GNU bash是(类似于GNU libc和 Linux kernel免费软件,您可以下载它的源代码并研究它,编译和改进它

You can use strace(1) or gdb(1) to understand how GNU bash (or any other Linux application) works.您可以使用strace(1)gdb(1)来了解 GNU bash(或任何其他 Linux 应用程序)如何工作。

Of course, globbing is done by the shell (before fork(2) and execve(2) ...), not by the /bin/ls process当然,通配是由 shell 完成的(在fork(2)execve(2) ...之前),而不是/bin/ls进程

How is shell expanding the * as in ls -l * shell 如何像ls -l *一样扩展*

When meeting a globing pattern like * , the shell reads all the directory entries and compare them one by one with the pattern.当遇到像*这样的通配模式时,shell 会读取所有目录条目并与模式一一进行比较。

A quick glance at the source code tells me this is probably done inglob.c , especially in the glob_vector() function.快速浏览一下源代码告诉我这可能是在glob.c中完成的,尤其是在glob_vector() function 中。

Is there any system calls happening behind the scene to read all the file in the directory?是否有任何系统调用在后台发生以读取目录中的所有文件?

Of course, you cannot read the content of a directory without the help of the kernel.当然,如果没有 kernel 的帮助,您将无法读取目录的内容。

That said, system calls are low-level, so don't expect to find any call to opendir() and readdir() which are libc calls.也就是说,系统调用是低级的,所以不要期望找到任何对opendir()readdir()的调用,它们是 libc 调用。 Rather, you will find calls to open() and getdents() / getdents64() instead.相反,您会发现对open()getdents() / getdents64()的调用。

I tried strace but not showing any system calls specific to globbing我尝试了 strace 但没有显示任何特定于 globbing 的系统调用

strace is NOT the right tool for that. strace不是正确的工具。 This is not your kernel that is doing globing, this is your shell, possibly with the help of libc functions, therefore there is no system call involved (except from the above-mentioned low-level calls to read the directory content).这不是你的 kernel 正在做 globing,这是你的 shell,可能在 libc 函数的帮助下,因此不涉及系统调用(除了上述读取目录内容的低级调用)。

If you want to trace calls to library functions like opendir() , readdir() , glob() , strcmp() ,... you MUST use ltrace :如果你想跟踪对opendir()readdir()glob()strcmp()等库函数的调用,你必须使用ltrace

ltrace bash -c 'ls *'

That said, Bash has its own globing system, more advanced than the basic one specified by the POSIX standard, so it won't rely on library functions like glob() or fnmatch() .也就是说,Bash 有自己的全局系统,比 POSIX 标准指定的基本系统更先进,因此它不会依赖像glob()fnmatch()这样的库函数。 Don't expect to see calls to them in ltrace output.不要期望在ltrace output 中看到对它们的调用。

If your aim is to use globbing in your own application and study how it is done, you may want to have a look at glob() which is simpler than Bash's globbing (FYI, I recently posted an example of use here ).如果您的目标是在自己的应用程序中使用 globbing 并研究它是如何完成的,您可能想看看glob() ,它比 Bash 的 globbing 更简单(仅供参考,我最近在这里发布了一个使用示例)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM