Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 检查路径是否指向文件_Bash_File - Fatal编程技术网

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,那么您确实应该使用
[