![Bash:通配符和文件条件](https://linux22.com/image/162627/Bash%EF%BC%9A%E9%80%9A%E9%85%8D%E7%AC%A6%E5%92%8C%E6%96%87%E4%BB%B6%E6%9D%A1%E4%BB%B6.png)
我正在尝试检查文件是否存在:这按预期工作:
if [ -e "/tmp/test.*.lock" ]; then
echo "exists!"
fi
这不会:
if [[ -e /tmp/test.*.lock ]]; then
echo "exists!"
fi
文件名可能类似于 /tmp/test.123.lock
我找不到让它与“[[”版本一起工作的方法。有人可以解释一下为什么以及如何让它发挥作用吗?
答案1
[[
用户 xenoid 我们是对的,表达式中不会发生路径名扩展。
从 bash 手册页:
[[ expression ]]
根据条件表达式的计算结果返回 0 或 1 的状态。表达式由下面描述的原色组成CONDITIONAL EXPRESSIONS
。 不对[[
和之间的单词执行分词和路径名扩展]]
;执行波形符扩展、参数和变量扩展、算术扩展、命令替换、进程替换和引号删除。诸如此类的条件运算符-f
必须不加引号才能被识别为主运算符。
(强调我的)
要使用[[
测试,需要在实际测试之前进行扩展。这可以借助数组来存储生成的文件名来完成。
下面是两个示例:第一个测试一个匹配文件,第二个测试至少一个匹配文件,如果找到匹配则退出循环。
files=( /tmp/test.*.lock )
# test if exactly one file matches
if [[ "${#files[@]}" -eq 1 ]] && [[ -e "${files[0]}" ]]; then
echo "file ${files[0]} exists!"
fi
# test if at least one file matches
for f in "${files[@]}"; do
if [[ -e "$f" ]]; then
echo "at least one file exists!"
break
fi
done
请注意,您不需要在[[
表达式中的变量周围加上引号,但这样做并没有什么坏处,您可以替换[[
为[
.如果您知道您的锁定文件是常规文件,请改用-f
。
答案2
[
是一个命令(实际上是一个 shell 内置命令,它是 的优化/usr/bin/[
,就像对echo
和等其他命令所做的printf
那样),因此后面的任何内容都会像任何命令一样进行文件名扩展。
[[
是 bash 关键字。看来文件扩展并未在括号内执行(但我在 bash 参考手册中找不到任何有关此内容的信息)。