Bash 使用tilde~expansion测试主目录时出现负值

Bash 使用tilde~expansion测试主目录时出现负值,bash,expansion,home-directory,tilde,bash4,Bash,Expansion,Home Directory,Tilde,Bash4,我犯了一个奇怪的错误,似乎不知道为什么 特别是因为它在一个地方有效,但在另一个场景中无效 我有他的代码检查这些目录是否存在- 带~的主目录在此代码段中失败: if [[ ! -d "$valueToTest" ]]; then echo 'Failed>>:'$valueToTest; fi; 我得到输出: Failed>>:~/.workspace/ Failed>>:~/.ssh Failed>>:~/.workspace/vim/t

我犯了一个奇怪的错误,似乎不知道为什么

特别是因为它在一个地方有效,但在另一个场景中无效

我有他的代码检查这些目录是否存在- 带~的主目录在此代码段中失败:

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
就像我说的,只有使用~扩展才能表示我的主目录

这是唯一发生这种情况的地方,因为我有其他代码,用~ie my HOME directory和~expansion检查路径,它们工作正常

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

我试过有双引号和没有双引号-没有运气

例如:

$valueToTest
${valueToTest}
"${valueToTest}"
谢谢您的帮助。

在以任何方式引用
~
时都不会发生。与之不同,
~
作为变量的一部分时也不会展开

如果
$valueToTest
~/.workspace/
,则所有这些表单都不起作用:

[[ ! -d "$valueToTest" ]]
[[ ! -d $valueToTest ]]
[ ! -d $valueToTest ]
这只是同义词:

test ! -d '~/.workspace/'
但这是可行的:

test ! -d ~/.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
eval
展开字符串。到目前为止,我发现足够好和安全:

printf -v temp %q "$valueToTest"
eval "valueToTest=$temp"
然后按您的方式测试
$valueToTest

更新 在Bash4.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}

这是我要求的答案。祝你好运。konsolebox-这对我不起作用:printf-v valueTemp%q“$valueToTest”;评估“valueToTest=$valueTemp”;;我还尝试从关联的数组中赋值,因为在代码的另一部分中,这是有效的:ls-al${gA_SysLocalPATH[HOME/.ssh]}。只有从文件加载这些数组时,这些测试才不起作用。但是,如果我在bash代码中直接赋值,比如${gA_SysLocalPATH[HOME/.ssh]}=~/.ssh——它们似乎可以工作。konsolebox——在读取文件时,我甚至在稍后(如上所述)将代码赋值到我测试的数组之前,在读取文件中的值之后,尝试了您的代码。只有当我从文件中读取这些值时,我才有这个问题。@mono dr您应该使用
-x
运行脚本,例如
bash-x script.sh
,并用它的输出更新您的问题。我的脚本是.bash\u别名的一部分。我将其编写为由.bash_别名调用的函数(在另一个文件中)。我试着像上面那样使用-x调用函数,但是没有成功。有没有办法像上面那样调用此函数-不将其移动到新文件?我还尝试将~替换为$HOME,并将其指定为keyValue=“$value”,以便$value中的$HOME可以扩展,但它也不起作用。非常感谢。
valueToTest=${valueToTest//\~/$HOME}
valueToTest=${valueToTest//\$HOME/$HOME}