我最近对linux的内部特性非常感兴趣,并且正在尝试理解它是如何工作的。
我知道当我输入ls
opendir()-函数被调用;
readdir()-为目录数据存储中的每个目录项调用的函数;
stat()-如果需要,可以调用函数获取有关文件的其他信息。
如果我遗漏了什么或是错了,请纠正我。
对我来说神秘的部分是文件扩展(globbing)。
我比较了strace ls的输出

open(".", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFDIR|0755, st_size=270336, ...}) = 0
getdents(3, /* 14 entries */, 32768)    = 440
getdents(3, /* 0 entries */, 32768)     = 0
close(3)                                = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
write(1, "2q.c  ds.c  fglob  fnoglob\n", 272q.c  ds.c  fglob  fnoglob

以及strace ls *.c
stat("2q.c", {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
lstat("2q.c", {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
stat("ds.c", {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
lstat("ds.c", {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
write(1, "2q.c  ds.c\n", 112q.c  ds.c
)            = 11

从我有限的知识可以看出,在第一种情况下,它的行为确实如我所期望的那样open, stat后跟getdents
但是后面的一个,对于shell globbing我并不清楚,因为它已经有一个文件列表,与模式匹配。这个名单是从哪里来的?
谢谢!

最佳答案

在调用实用程序之前,命令行上的shell globbing模式由shell展开。
您可以通过在shell中使用set -x启用跟踪来看到这一点:

$ set -x
$ ls -l f*
+ ls -l file1 file2 file3
-rw-r--r--  1 kk  wheel  0 May 11 16:49 file1
-rw-r--r--  1 kk  wheel  0 May 11 16:49 file2
-rw-r--r--  1 kk  wheel  0 May 11 16:49 file3

如您所见,shell告诉您它调用了什么命令(在+提示符处),并且它已经在命令行上展开了模式。
ls命令不执行文件名全局搜索。事实上,如果您引用globbing模式来保护它不受shell的影响,那么ls肯定会混淆:
$ ls -l 'f*'
+ ls -l f*
ls: f*: No such file or directory

(当然,除非当前目录中确实存在名为f*的内容)。

关于linux - 当执行`ls * .c`时,内部会发生什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50294360/

10-15 10:33