波形符扩展 https://www.gnu.org/s/bash/manual/html_node/Tilde-Expansion.html不会发生当~
以任何方式引用。并且不像路径名或文件名扩展 https://www.gnu.org/s/bash/manual/html_node/Filename-Expansion.html, ~
当它是变量的一部分时也不会扩展。
If $valueToTest
is ~/.workspace/
,所有这些形式都不起作用:
[[ ! -d "$valueToTest" ]]
[[ ! -d $valueToTest ]]
[ ! -d $valueToTest ]
并且只是同义词:
test ! -d '~/.workspace/'
但这会起作用:
test ! -d ~/.workspace/
Or
test ! -d /home/user/.workspace/
因此,对代码的修复是,您应该将扩展路径分配给变量,而不是未扩展的形式:
valueToTest=~/.workspace/ ## Correct assignment.
valueToTest=~'/.workspace/' ## Correct assignment.
valueToTest=~"/.workspace/" ## Correct assignment.
valueToTest='~/.workspace/' ## Incorrect assignment.
valueToTest="~/.workspace/" ## Incorrect assignment.
set -- ~/.workspace/ ## Correct assignment.
valueToTest=$1 ## (simulates bash script.sh ~/.workspace/)
set -- "~/.workspace/" ## Incorrect assignment.
valueToTest=$1
The Hack
如果不可避免地只存储未展开的形式,您可以使用printf %q
and eval
来扩展你的字符串。到目前为止,我发现足够好并且安全:
printf -v temp %q "$valueToTest"
eval "valueToTest=$temp"
然后测试$valueToTest
就像你做的那样。
Update
在 Bash 4.3 中,printf %q
已经会引用波浪号字符(~
)也是如此。要解决此问题,您可以再次取消引用这些字符:
printf -v temp %q "$valueToTest"
temp=${temp//\\\~/\~}
eval "valueToTest=$temp"
您还可以允许$HOME
扩大:
printf -v temp %q "$valueToTest"
temp=${temp//\\\~/\~}
temp=${temp//\\\$HOME/\$HOME}
eval "valueToTest=$temp"
另一种可能的修复方法是直接转换它们:
valueToTest=${valueToTest//\~/$HOME}
valueToTest=${valueToTest//\$HOME/$HOME}