Bash:通配符和文件条件

Bash:通配符和文件条件

我正在尝试检查文件是否存在:这按预期工作:

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 参考手册中找不到任何有关此内容的信息)。

相关内容