在什么情况下,文件通配符在 bash 中不起作用?

Kur*_*ler 2 unix bash glob du

如果我在sudo du -sh <some_directory>/*需要 root 访问权限的目录上运行,它会工作并列出 . 然而,我发现至少有一种情况不会发生这种情况:

sudo du -sh /var/lib/docker/*

http://tldp.org/LDP/abs/html/globbingref.html没有提到任何预计这不起作用的场景。有谁知道为什么这可能行不通?它与 Docker 有关还是du与 globbing 完全有关。

Alf*_*lfe 5

评论已经简短地提到了这一点,但为了对这个问题有一个体面的答案和更详细的解释:

在命令中

sudo du -sh /var/lib/docker/*
Run Code Online (Sandbox Code Playgroud)

您正在执行的通配符发生在执行之前sudo。只有 的调用du是用 root 权限完成的。/var/lib/docker/这意味着,如果您作为普通用户限制该目录并且您无法读取它(缺少r权限),则通配星号将不会计算出任何内容。then中的默认设置bash是保持不变,因此字符串保持不变/var/lib/docker/*

然后将参数du-sh/var/lib/docker/*传递给sudo它,然后du以 root 权限执行并传递参数-sh/var/lib/docker/*du然后尝试查找具有完全相同名称的文件,并且可能什么也找不到,因为其中没有名为 的文件*

确实实现了您想要的目标,您也需要使用 root 权限来完成通配。为此,您需要使用 root 权限启动 shell(只有 shell 执行通配操作):

sudo bash -c 'du -sh /var/lib/docker/*'
Run Code Online (Sandbox Code Playgroud)

这样,参数bash-cdu -sh /var/lib/docker/*就会传递给命令sudo。然后以 root 权限sudo启动bash并传递命令-c, du -sh /var/lib/docker/*。然后,bash由于-c应该评估和执行命令的选项,因此可以理解du -sh /var/lib/docker/*。然后,它将命令按空格分割成“单词” du-sh/var/lib/docker/*/var/lib/docker/现在,它对每个单词执行任何必要的通配扩展(具有 root 权限,因此允许读取目录的内容)。它将用/var/lib/docker/aufs/var/lib/docker/builder/var/lib/docker/buildkit等几个单词替换最后一个单词。作为最后一步,它将调用du-sh通配扩展的结果。Root 权限将被继承,因此du也可以使用它们运行。