arrays - bash“if”语句中 glob 的奇怪行为
问题描述
我只是遇到了这种奇怪的行为,但我在任何地方都找不到它的记录。在我完全理解它之前,我很犹豫在我的脚本中使用它。有人可以解释下面的行为吗?
本质上,在我的if
声明中,我正在询问当前文件夹中是否存在所有编号的文件,并根据该现实打印一份声明。
如果只有 file1.zip
并且file3.zip
存在,就会发生这种情况:
> if [ -s file1.zip ] && [ -s file2.zip ] && [ -s file3.zip ] && [ -s file4.zip ]
> then
> echo All numbers[1-4] exist
> else
> echo Only numbers[1-4] exist so far
> fi
Only numbers[1-4] exist so far
这是我所期望的。但是,当语句更改为实际匹配语句中的文件名时if
,会发生一些有趣的事情:
> if [ -s file1.zip ] && [ -s file2.zip ] && [ -s file3.zip ] && [ -s file4.zip ]
> then
> echo All file[1-4].zip exist
> else
> echo Only file[1-4].zip exist so far
> fi
Only file1.zip file3.zip exist so far
现在写出文件名。与此行为一致,当if
语句被压缩时,行为重复:
> if [[ -s file[1-4].zip ]]
> then
> echo All file[1-4].zip exist
> else
> echo Only file[1-4].zip exist so far
> fi
Only file1.zip file3.zip exist so far
因此,当所有文件都存在时,会发生以下情况:
> if [ -s file1.zip ] && [ -s file2.zip ] && [ -s file3.zip ] && [ -s file4.zip ]
> then
> echo All numbers[1-4] exist
> else
> echo Only numbers[1-4] exist so far
> fi
All numbers[1-4] exist
> if [ -s file1.zip ] && [ -s file2.zip ] && [ -s file3.zip ] && [ -s file4.zip ]
> then
> echo All file[1-4].zip exist
> else
> echo Only file[1-4].zip exist so far
> fi
All file1.zip file2.zip file3.zip file4.zip exist
但是,在最后一种情况下,由于某种原因,压缩语句的计算结果为,false
但所有文件名仍被写出:
> if [[ -s file[1-4].zip ]]
> then
> echo All file[1-4].zip exist
> else
> echo Only file[1-4].zip exist so far
> fi
Only file1.zip file2.zip file3.zip file4.zip exist so far
从本质上讲,我的困惑有两个方面:
- 类似数组的行为究竟是如何工作的,为什么像这样的术语没有
numbers[1-4]
展开成单独的术语,但文件的特定名称 (file[1-4].zip
) 确实(即 intofile1.zip file3.zip
)? if
为什么当语句写出(if [ -s file1.zip ] && [ -s file2.zip ] && [ -s file3.zip ] && [ -s file4.zip ]
)与浓缩( )时行为不一致if [[ -s file[1-4].zip ]]
?
解决方案
事实:
[1-4]
是一个匹配数字 1 到 4 的全局模式。- 将glob 模式(例如
*.txt
or[1-4].txt
)扩展为单词列表称为文件名扩展。 - 分词和文件名扩展不在参数内部执行
[[
]]
。
结论:
file[1-4].zip
当一个参数echo
扩展为与模式匹配的文件列表时。[[ -s file[1-4].zip ]]
检查一个名为字面意思file[1-4].zip
的文件。IE。它与 相同[[ -s 'file[1-4].zip' ]]
。
为什么像 numbers[1-4] 这样的术语不展开成单独的术语
当一个 glob 不匹配任何文件时,它不会被扩展并“停留”并且在没有任何更改的情况下传递(除了 when shopt -s nullglob
,在这种情况下它会消失)。您没有名为numbers1
ornumbers2
或numbers3
or的文件numbers4
。创建这样的文件numbers[1-4]
并将扩展到它们。
文件的具体名称 (file[1-4].zip)
因为你有file1.zip
和file3.zip
。删除这些文件,它将保留。
为什么写 if 语句时行为不一致...
因为[[
与任何其他命令不同,它由 bash 超级特殊处理。这些是与[[
]]
. 请参阅bash 手册 [[ 表达式.
推荐阅读
- javascript - 无法在数组中添加元素
- python - Django 在测试时总是返回 404。“在此服务器上找不到请求的资源。”
- jquery - 使用动画 SASS 混合时遇到问题
- reactjs - Typescript - 从对象道具值推断泛型类型
- clips - 当 CLIPS 与 .NET 集成时,CLIPS 中的打开功能不起作用
- java - 在菜单中创建子菜单是否有更有效的方法
- python-3.x - 如何使用 pyenv 在 Matlab 中更新运行 Python 的 Python 版本?
- mysql - MySQL 操作开销和处理大表
- jekyll - 如何使用 Pandoc 将 Word 转换为 Markdown
- javascript - 通过 API javascript 显示对象数组(for 循环与 for in 循环)