0

简单的问题,但显然我自己无法找到答案。

我读取用户的输入并将其保存到$database_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

即使我输入了一个有效的数据库路径,它也不会检测到它何时是一个有效的文件(我已经用值替换了名称等)。

~/company/files/database.sqlite

每次它只是说它不是一个有效的文件。请帮忙。

4

3 回答 3

2

其他人已经解释了为什么你的代码失败得很好。剩下的就是指出readlink一个可能的解决方案:

readlink -e ~/company/files/database.sqlite

这将为您提供绝对(扩展)路径 / $? == 0 如果文件存在,什么都没有 / $? == 1 如果不是,无论您当前的工作目录如何。

但请记住,它readlink属于 GNU coreutils;虽然很普遍(例如 Linux、Cygwin),但它并非无所不在(例如 AIX)。

于 2013-04-17T11:32:41.070 回答
1

正如@michaelb958 提到的;您得到的错误是由于~没有扩展到 $HOME。有2种可能的解决方案

1) 更改[ -f "$database_path" ]为,[ -f $database_path ]以便不~引用并将扩展。

2)正如@michaelb958所提到的;如果您必须绝对需要引号,则可以提供相对于当前目录的完整路径或路径$database_path

于 2013-04-17T11:23:03.143 回答
1

假设您正在输入表单的文件路径~/.../foo.sqlite

Bash tilde-expansion 不会在参数扩展所在的任何地方调用。从手册页(至少,这个副本):

如果单词以不带引号的波浪号字符 ('~') 开头,则第一个不带引号的斜杠之前的所有字符(或所有字符,如果没有不带引号的斜杠)都被视为波浪号前缀。如果波浪号前缀中没有任何字符被引用,波浪号后面的波浪号前缀中的字符将被视为可能的登录名。如果此登录名是空字符串,波浪号将替换为 shell 参数 HOME 的值。如果 HOME 未设置,则替换执行 shell 的用户的主目录。否则,波浪号前缀将替换为与指定登录名关联的主目录。

[...]

每个变量赋值都会检查紧跟在 : 或第一个 = 之后的未加引号的波浪号前缀。在这些情况下,也执行波浪号扩展。因此,可以在分配给 PATH、MAILPATH 和 CDPATH 时使用带有波浪号的文件名,并且 shell 分配扩展值。

read database_path不会扩大波浪号,其他任何东西都不会扩大,包括[ -f "$database_path" ]. 因此,该[命令将查找$PWD/~/...,而不是$HOME/...

这可以通过使用绝对路径(以 开头/)或相对于当前目录的路径来解决。

警告:我现在没有 Bash,所以这是未经测试的。编辑:我在 MinGW Bash(3.1.17(1)-release)上对其进行了测试;理论得到证实。)

于 2013-04-17T10:36:10.907 回答