StuStirling
StuStirling

Reputation: 16191

Checking Whether Path Leads To A File

Simple question but apparently I am unable to find the answer myself.

I read an input from a user and save it to $database_path

From there I see if the variable is set. If it isn't I quit if it is I then check whether the path leads to a file. Below is my code..

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

Even when I input a valid database path like so it won't detect when its a valid file (I have substituted values for names etc).

~/company/files/database.sqlite

Everytime it just says its not a valid file. Please help.

Upvotes: 0

Views: 190

Answers (3)

DevSolar
DevSolar

Reputation: 70263

The others have explained why your code fails quite nicely. All that is left to me is to point to readlink for a possible solution:

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

This will give you the absolute (expanded) path / $? == 0 if the file exists, and nothing / $? == 1 if it doesn't, regardless of your current work directory.

Keep in mind, though, that readlink belongs to GNU coreutils; while widespread (e.g. Linux, Cygwin) it is not omnipresent (e.g. AIX).

Upvotes: 2

Navaneeth Krishnan M
Navaneeth Krishnan M

Reputation: 141

As @michaelb958 mentioned; the error you are getting is due to ~ not being expanded to $HOME. There are 2 possible solutions

1) change [ -f "$database_path" ] to [ -f $database_path ] so that the ~ is unquoted and will be expanded.

2) As @michaelb958 mentioned; you could give full paths or paths relative to your current directory if you must absolutely need the quotes around $database_path.

Upvotes: 1

Assuming you're entering filepaths of the form ~/.../foo.sqlite

Bash tilde-expansion is not invoked everywhere parameter expansion is. From the manpage (at least, this copy):

If a word begins with an unquoted tilde character ('~'), all of the characters preceding the first unquoted slash (or all characters, if there is no unquoted slash) are considered a tilde-prefix. If none of the characters in the tilde-prefix are quoted, the characters in the tilde-prefix following the tilde are treated as a possible login name. If this login name is the null string, the tilde is replaced with the value of the shell parameter HOME. If HOME is unset, the home directory of the user executing the shell is substituted instead. Otherwise, the tilde-prefix is replaced with the home directory associated with the specified login name.

[...]

Each variable assignment is checked for unquoted tilde-prefixes immediately following a : or the first =. In these cases, tilde expansion is also performed. Consequently, one may use file names with tildes in assignments to PATH, MAILPATH, and CDPATH, and the shell assigns the expanded value.

read database_path will not expand the tilde, and neither will anything else up to and including [ -f "$database_path" ]. Thus, the [ command will look for $PWD/~/..., rather than $HOME/....

This can be fixed by using either absolute paths (starting with /) or paths relative to the current directory.

(Warning: I don't have a Bash on me right now, so this is untested. Edit: I tested it on the MinGW Bash (3.1.17(1)-release) I had lying around; theory confirmed.)

Upvotes: 1

Related Questions