当我在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 ]
被识别为有效的目录名。
我尝试了中提供的解决方案如何在bash中手动展开特殊变量(例如:~ tilde),但它只适用于波浪,而不适用其他相对路径,如../
,../../
或./
我尝试了if
语句中引用/双引号和单/双方括号的变化,并在所有情况下得到相同的错误。这些错误发生在MSYS2 (Git Bash)和Ubuntu 22上。
~/tmp
实际上从bash的角度来看是绝对路径。但是,这依赖于bash将~
替换为用户帐户的主文件夹路径,因此要替换为/home/users/someone/tmp
之类的东西,这显然是绝对路径。这是bash shell的一个内置特性,通常称为"路径扩展"。相对路径可能是./tmp
或tmp
之类的东西,因此必须将相对解释为进程的当前工作目录。
这个替换显然没有在这里应用。通过显式地在子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
指令是一个非常强大的工具…