~
以任何方式引用时都不会发生波浪号扩展。与路径名或文件名扩展不同,~
当它是变量的一部分时也不会扩展。
如果$valueToTest
是~/.workspace/
,所有这些形式都不起作用:
[[ ! -d "$valueToTest" ]]
[[ ! -d $valueToTest ]]
[ ! -d $valueToTest ]
并且只是同义词:
test ! -d '~/.workspace/'
但这会起作用:
test ! -d ~/.workspace/
或者
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
黑客
如果只能存储未展开的形式是不可避免的,您可以使用printf %q
andeval
来展开您的字符串。到目前为止,我发现足够好且安全:
printf -v temp %q "$valueToTest"
eval "valueToTest=$temp"
然后测试$valueToTest
你的做法。
更新
在 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}