使用bash中的主字符(〜)检查目录是否存在失败


16

为什么以下bash检查目录是否失败?

if [ ! -d "~/Desktop" ]; then
   echo "DOES NOT EXIST"
   exit 1;
fi

~/Desktop确实存在。顺便说一下,这是在Mac上。


问题是这种类型的脚本

read -p "Provide the destination directory: " DESTINATION

if [ ! -d $DESTINATION ]; then
    echo "\t'$DESTINATION' does not exist." >&2;
    exit 1;
fi

1
就像执行操作时一样,cd "~/Desktop"您也会收到错误消息。它必须不加引号或存储为变量(不带引号)。例如,a=~/Desktop; cd $a;工作原理,但并不a="~/Desktop"; cd Desktop;serverfault.com/questions/417252/...
dylnmc

Answers:


7

贾斯汀(Justin)在对量子答案的第一篇评论中澄清了他的问题。他正在使用read(或通过其他一些动态方式)阅读一行文本,并希望扩展波浪线。

问题变成“如何对变量的内容执行波浪号扩展?”

通用方法是使用eval,但是它带有一些重要的警告,即>变量中的空格和输出重定向()。以下内容似乎对我有用:

read -p "Provide the destination directory: " DESTINATION

if [ ! -d "`eval echo ${DESTINATION//>}`" ]; then
    echo "'$DESTINATION' does not exist." >&2;
    exit 1;
fi

尝试使用以下每个输入:

~
~/existing_dir
~/existing dir with spaces
~/nonexistant_dir
~/nonexistant dir with spaces
~/string containing > redirection
~/string containing > redirection > again and >> again

说明

  • ${mypath//>}剔除>这可能在揍一个文件中的字符eval
  • eval echo ...是什么是实际的波浪线扩展
  • 的双引号eval用于支持带空格的文件名。

作为对此的补充,您可以通过添加以下-e选项来改进UX :

read -p "Provide the destination directory: " -e DESTINATION

现在,当用户键入波浪号并单击选项卡时,它将展开。但是,此方法不能代替上面的评估方法,因为扩展仅在用户单击选项卡时发生。如果他只是输入〜/ foo并按回车,它将保留为波浪号。

也可以看看:


23

删除目录周围的双引号以查看其是否有效:

if [ ! -d ~/Desktop ]; then
   echo "DOES NOT EXIST"
   exit 1;
fi

其原因是波浪号扩展名仅在未引用时才起作用。

info "(bash) Tilde Expansion"

3.5.2 Tilde Expansion
---------------------

If a word begins with an unquoted tilde character (`~'), all of the
characters up to the first unquoted slash (or all characters, if there
is no unquoted slash) are considered a TILDE-PREFIX.  If none of the
characters in the tilde-prefix are quoted, the characters in the
tilde-prefix following the tilde are treated as a possible LOGIN NAME.
If this login name is the null string, the tilde is replaced with the
value of the `HOME' shell variable.  If `HOME' is unset, the home
directory of the user executing the shell is substituted instead.
Otherwise, the tilde-prefix is replaced with the home directory
associated with the specified login name.

如果值是动态输入的,该怎么办。即(pastie.org/4471350)并且DESTINATION~/Desktop
贾斯汀2012年

3
波浪扩展是在设置变量时进行的,而不是在求值时进行的,因此这不是一个公平的例子。
MadHatter

+1,这足以解决我的问题。
飞翔的费舍尔2016年


1

echo $HOME

使用$HOME,并确保用户实际上正在使用脚本。如果root使用~它来查找/root,则不行/home/$USER

if [ ! -d "$HOME/Desktop" ]; then
   echo "DOES NOT EXIST"
   exit 1;
fi

-1
if [ ! -d "$HOME/Desktop" ]; then
   echo "DOES NOT EXIST"
   exit 1;
fi

应该是$ HOME而不是〜

〜是键盘的东西


如果您在此处阅读其他答案,您将意识到这是错误的。
小鸡
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.