shell 如何将相对目录名转换为Bash可识别的绝对目录名?

kt06eoxx  于 2022-12-04  发布在  Shell
关注(0)|答案(1)|浏览(135)

当我在Bash中使用“read”命令输入相对目录路径名时,-d测试无法将其识别为有效目录:
相对目录路径~/tmp未通过if/-d测试:

corba@samwise:~$ read CMDLINE_FILENAME
~/tmp
corba@samwise:~$ echo "$CMDLINE_FILENAME"
~/tmp
corba@samwise:~$ if [ -d $CMDLINE_FILENAME ]; then echo "Valid directory!"; fi
corba@samwise:~$

相对目录路径../tmp未通过if/-d测试:

corba@samwise:bin$ read CMDLINE_FILENAME
../tmp
corba@samwise:bin$ echo "$CMDLINE_FILENAME"
../tmp
corba@samwise:bin$ if [ -d $CMDLINE_FILENAME ]; then echo "Valid directory!"; fi
corba@samwise:~$

但绝对目录路径成功:

corba@samwise:~$ read CMDLINE_FILENAME
/home/corba/tmp
corba@samwise:~$ echo "$CMDLINE_FILENAME"
/home/corba/tmp
corba@samwise:~$ if [ -d $CMDLINE_FILENAME ]; then echo "Valid directory!"; fi
Valid directory!
corba@samwise:~$

我希望if [ -d ~/tmp ]if [ -d ../tmp ]被识别为有效的目录名,但事实并非如此。
我尝试了How to manually expand a special variable (ex: ~ tilde) in bash中提供的解决方案,但它只适用于代字号,不适用于其他相对路径,如../../.././
我在if语句中尝试了引号/双引号和单/双方括号的变体,在所有情况下都得到了相同的错误。这些错误发生在MSYS 2(Git Bash)和Ubuntu 22上。

koaltpgm

koaltpgm1#

从bash的Angular 来看,~/tmp实际上 * 是 * 一个绝对路径。然而,这依赖于bash将~替换为用户帐户的主文件夹路径,例如/home/users/someone/tmp,这显然是一个绝对路径。这是bash shell的一个内置特性,通常称为“路径扩展”。相对路径可能是./tmptmp,因此必须相对于进程的当前工作目录进行解释。
这种替换显然在这里没有得到应用。你可以使用一个稍微改变的命令来实现你所寻找的目标,方法是在一个子shell命令中显式地强制这样的扩展:

if [ -d `eval echo $CMDLINE_FILENAME` ]; then echo "Valid directory!"; fi

该方法适用于绝对路径和相对路径,但也适用于依赖于bash路径扩展的条目:

bash:~$ read CMDLINE_FILENAME 
~/tmp
bash:~$ echo "$CMDLINE_FILENAME"
~/tmp
bash:~$ if [ -d `eval echo $CMDLINE_FILENAME`]; then echo "Valid directory!"; fi 
Valid directory!

但是,这样做确实会有遗漏使用的风险:eval指令是一个非常强大的工具...

相关问题