Bash 检查路径是否指向文件
这个问题很简单,但显然我自己找不到答案 我从用户处读取输入并将其保存到Bash 检查路径是否指向文件,bash,file,Bash,File,这个问题很简单,但显然我自己找不到答案 我从用户处读取输入并将其保存到$database\u path 从那里我可以看到变量是否被设置。如果不是,我退出如果是,我检查路径是否指向文件。下面是我的代码 read database_path echo "database path = $database_path" if [ -z $database_path ]; then echo "Error: You must enter a path to the database"
$database\u path
从那里我可以看到变量是否被设置。如果不是,我退出如果是,我检查路径是否指向文件。下面是我的代码
read database_path
echo "database path = $database_path"
if [ -z $database_path ]; then
echo "Error: You must enter a path to the database"
exit
elif [ ! -f "$database_path" ]
then
echo "Error: Path \"$database_path\" does not lead to a file"
exit
fi
即使我输入了一个有效的数据库路径,比如,它也不会检测到它是一个有效的文件(我用值代替了名称等)
每次它只是说它不是一个有效的文件。请提供帮助。假设您输入的文件路径为~/…/foo.sqlite
在参数展开的任何地方都不会调用Bash tilde展开。从手册页(至少,):
如果单词以不带引号的波浪号字符(“~”)开头,则第一个不带引号的斜杠前面的所有字符(或如果没有不带引号的斜杠,则所有字符)都被视为波浪号前缀。如果tilde前缀中没有任何字符被引用,则tilde后面的tilde前缀中的字符将被视为可能的登录名。如果此登录名为空字符串,则波浪号将替换为shell参数HOME的值。如果HOME未设置,则替换执行shell的用户的HOME目录。否则,tilde前缀将替换为与指定登录名关联的主目录
[……]
每个变量赋值都会检查:或第一个=,后面是否有未加引号的波浪号前缀。在这些情况下,也会执行tilde扩展。因此,在分配给PATH、MAILPATH和CDPATH时,可以使用带波浪号的文件名,shell分配扩展值
read database\u path
将不会展开平铺,并且在[-f“$database\u path”]
之前及之后的任何内容也不会展开平铺。因此,[
命令将查找$PWD/~/..
,而不是$HOME/..
这可以通过使用绝对路径(从/
开始)或相对于当前目录的路径来修复
(警告:我现在没有Bash,所以这是未经测试的。编辑:我在我的MinGW Bash(3.1.17(1)-版本)上测试了它,理论得到了证实。)假设您正在输入表单的文件路径~/../foo.sqlite
在参数展开的任何地方都不会调用Bash tilde展开。从手册页(至少,):
如果单词以不带引号的斜杠字符(“~”)开头,则第一个不带引号的斜杠前面的所有字符(或如果没有不带引号的斜杠,则为所有字符)被视为tilde前缀。如果tilde前缀中没有任何字符被引用,则tilde后面的tilde前缀中的字符将被视为可能的登录名。如果此登录名为空字符串,则tilde将替换为shell参数HOME的值。如果HOME未设置,则执行e shell被替换。否则,tilde前缀将替换为与指定登录名关联的主目录
[……]
每个变量赋值都会在:或第一个=之后立即检查是否有未加引号的tilde前缀。在这些情况下,也会执行tilde扩展。因此,在PATH、MAILPATH和CDPATH的赋值中,可以使用带有tilde的文件名,shell会分配扩展的值
read database\u path
不会展开平铺图,也不会展开[-f“$database\u path”]
之前的任何内容。因此,[/code>命令将查找$PWD/~/…
,而不是$HOME/…
这可以通过使用绝对路径(从/
开始)或相对于当前目录的路径来修复
(警告:我现在没有Bash,因此这是未经测试的编辑:我在MinGW Bash(3.1.17(1)-发行版)上测试了它;理论得到了证实。)正如@michaelb958所提到的;您得到的错误是由于~
没有扩展到$HOME。有两种可能的解决方案
1) 将[-f“$database\u path”]
更改为[-f$database\u path]
,以便~
不带引号并将展开
2) 正如@michaelb958所提到的;如果您必须绝对需要@michaelb958所提到的$database\u path
周围的引号,您可以提供完整路径或相对于当前目录的路径;您得到的错误是由于~
没有扩展到$HOME。有两种可能的解决方案
1) 将[-f“$database\u path”]
更改为[-f$database\u path]
,以便~
不带引号并将展开
2) 正如@michaelb958所提到的;如果您必须绝对需要$database\u path
周围的引号,您可以提供完整路径或相对于当前目录的路径。其他人已经解释了代码失败的原因。我只需指向readlink
,以获得可能的解决方案:
readlink -e ~/company/files/database.sqlite
如果文件存在,这将为您提供绝对(扩展)路径/$?==0;如果文件不存在,则为nothing/$?==1,无论您当前的工作目录如何
但是请记住,readlink
属于GNU coreutils;虽然它很普遍(例如Linux、Cygwin),但它并不是无所不在(例如AIX)。其他人已经解释了为什么您的代码失败得很好。我只需要指出readlink
来寻找一个可能的解决方案:
readlink -e ~/company/files/database.sqlite
如果文件存在,这将为您提供绝对(扩展)路径/$?==0;如果文件不存在,则为nothing/$?==1,无论您当前的工作目录如何
但是,请记住,readlink
属于GNU coreutils;虽然广泛使用(例如Linux、Cygwin),但它并非无所不在(例如AIX)。如果您使用的是Bash,那么您确实应该使用[