使用波浪号〜扩展来测试HOME目录的负面效果

时间:2014-08-21 04:28:23

标签: bash expansion home-directory tilde bash4

我得到一个奇怪的错误,似乎无法弄清楚原因。

特别是因为它在一个地方工作,但在另一个地方不工作。

我有他的代码检查这些目录是否存在 - 在这段代码片段中,带有〜的HOME目录失败了:

if [[ ! -d "$valueToTest" ]]; then
    echo 'Failed>>:'$valueToTest;
fi;

我得到输出:

Failed>>:~/.workspace/
Failed>>:~/.ssh
Failed>>:~/.workspace/vim/temp
Failed>>:~/.workspace/vim/backup
Failed>>:~/.workspace/vim
Failed>>:~/test

就像我说的那样只有〜扩展代表我的HOME目录。

这是唯一发生这种情况的地方,因为我有其他代码用〜扩展检查路径〜即我的HOME目录,并且它们工作正常!

正在从关联数组的值部分读取目录 - 但我不明白为什么会出现问题。您还可以看到输出没有引号或与之相关的引号。

我曾经尝试过使用和不使用双引号 - 没有运气。

如:

$valueToTest
${valueToTest}
"${valueToTest}"

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

以任何方式引用~时都不会发生{p> Tilde expansion。与pathname or filename expansion不同,~在变量的一部分时也不会扩展。

如果$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

The Hack

如果仅存储未展开的表单是不可避免的,您可以使用printf %qeval来扩展字符串。到目前为止,我发现足够好和安全:

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}