I have a BASH script that is looking for a hidden file in my home directory. When I specify the absolute path /home/user/.foo
in trying to find the file then the script will find it but if I use ~/.foo
then the script cannot find the file. Can someone explain why this is happening and what other way I can find the file. I want to be able to find the file on different user's home directory and not just my own.
Sorry for not providing the snippet of code but here it is
file="~/.foo"
[ -f $file ] && echo "foo exists!"
this however works
file="home/user/.foo"
[ -f $file ] && echo "foo exists!"
This is because the shell only performs tilde expansion when the tilde is the first unquoted character in a word. In
file="~/.foo"
the tilde is quoted with double quotes, so is left unexpanded. The best practice is to always use $HOME
when the tilde is supposed to expand to your home directory (and not some other user's as in ~user
.
The straight dope from POSIX:
2.6.1 Tilde Expansion
A "tilde-prefix" consists of an unquoted <tilde> character at the beginning of a word, followed by all of the characters preceding the first unquoted <slash> in the word, or all the characters in the word if there is no <slash>. In an assignment (see XBD Variable Assignment), multiple tilde-prefixes can be used: at the beginning of the word (that is, following the <equals-sign> of the assignment), following any unquoted <colon>, or both. A tilde-prefix in an assignment is terminated by the first unquoted <colon> or <slash>. 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 from the user database. A portable login name cannot contain characters outside the set given in the description of the
LOGNAME
environment variable in XBD Other Environment Variables. If the login name is null (that is, the tilde-prefix contains only the tilde), the tilde-prefix is replaced by the value of the variableHOME
. IfHOME
is unset, the results are unspecified. Otherwise, the tilde-prefix shall be replaced by a pathname of the initial working directory associated with the login name obtained using thegetpwnam()
function as defined in the System Interfaces volume of POSIX.1-2008. If the system does not recognize the login name, the results are undefined.The pathname resulting from tilde expansion shall be treated as if quoted to prevent it being altered by field splitting and pathname expansion.
Always provide the code which does not work. From your description it cannot be reproduced:
$ ls ~/.foo
/home/user/.foo
As suggested by anishsane there may be quotes.
$ ls "~/.foo"
ls: cannot access ~/.foo: No such file or directory
But how to handle white space? Put the ~ outside the quotes:
$ ls ~/".f o o"
/home/user/.f o o
But also but the / outside the quotes, else ~ is not expanded
$ ls ~"/.f o o"
ls: cannot access ~/.f o o: No such file or directory
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With