bash diff 在提供包含波浪号 (~) 的路径变量时无法找到现有文件

bash diff fails to found existing files when providing a path variable containing tilde (~)

我在尝试在 bash 脚本中执行 diff 命令时遇到了一个非常令人惊讶的问题。

这是一个说明这一点的工作代码:

#!/bin/bash
cd
mkdir foo bar
head -c 1024 /dev/urandom >foo/qux
head -c 1024 /dev/urandom >bar/qux

# works properly as expected
diff ~/{foo,bar}/qux

folder="~"

# this fails with the ~ inside a variable
diff $folder/{foo,bar}/qux

# cleaning the mess
rm -rf foo bar

所以我的问题是:

为什么? :-)

在将 ~ 分配给变量时不要引用它。 ~ 仅在您不引用时扩展 bash。

~ 是 shell 扩展的一个特征。
双引号将扩展限制为仅三个特征:

  1. 命令替换:$(some command here)`some command here`
  2. 变量替换:$VAR${VAR}
  3. 算术:$((2+2))

所以当放在双引号内时,~ 不会展开

波浪号扩展仅适用于不带引号的波浪号。在对 folder 执行赋值时必须扩展波浪号,因为波浪号扩展不适用于参数扩展,仅适用于分词和路径名扩展。

folder=~  # ~ is expanded, and the result is assigned to folder