我有一个这样的目录结构:
.
├── 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/**/*.c
和dir_a[12]/**/*.c
。第二个扩展到唯一匹配的文件,dir_a1/src/file.c
但第一个不匹配任何内容,因此被保留(因此它会按字面回显)。
如果您不想传递不匹配的 glob,请设置nullglob
shell 选项 via shopt -s nullglob
。但请注意,这会导致其他事情以奇怪的方式运行,例如ls /etc/*.nosuchextension
列出当前目录的内容。处理不匹配的 glob 的另一种方法是failglob
shell 选项。