为什么路径名扩展是这样工作的?

为什么路径名扩展是这样工作的?

我有一个这样的目录结构:

.
├── dir
│   └── src
│       └── file.c
├── dir_a1
│   └── src
│       └── file.c
└── dir_a2
    └── src
        └── file.c

当我运行以下命令时,结果符合预期:

echo dir{,_a[12]}/**/*.c 
#
dir/src/file.c
dir_a1/src/file.c
dir_a2/src/file.c

如果我删除文件.c目录_a2,结果还是OK的:

rm dir_a2/src/file.c
echo dir{,_a[12]}/**/*.c
#
dir/src/file.c
dir_a1/src/file.c

但是当我删除文件.c目录,该目录的结果变得混乱:

rm dir/src/file.c
echo dir{,_a[12]}/**/*.c
#
dir/**/*.c
dir_a1/src/file.c

为什么 bash 决定删除扩展结果目录_a2但不是目录

全球星在 shell 中启用。

答案1

括号扩展(即{this,that,etc})是不是文件 glob,这意味着无论是否存在同名文件,它都会扩展到所有值。因此,dir{,_a[12]}/**/*.c扩展到两个 glob 模式dir/**/*.cdir_a[12]/**/*.c。第二个扩展到唯一匹配的文件,dir_a1/src/file.c但第一个不匹配任何内容,因此被保留(因此它会按字面回显)。

如果您不想传递不匹配的 glob,请设置nullglobshell 选项 via shopt -s nullglob。但请注意,这会导致其他事情以奇怪的方式运行,例如ls /etc/*.nosuchextension列出当前目录的内容。处理不匹配的 glob 的另一种方法是failglobshell 选项。

相关内容