0

I want to store a path I often use as an environment variable, then call this variable to construct a path name.

$ mypath="~/local/bin/"
$ newFile="${mypath}newFile.sh"
$ echo $newFile
~/local/bin/newFile.sh

That appears to work.

But, if I call $newFile as the input to touch, it fails:

$ touch $newFile
touch: ~/local/bin/newFile.sh: No such file or directory

$ touch "${mypath}newFile.sh"
touch: ~/local/bin/newFile.sh: No such file or directory

Both don't work. What am I missing?

P.S. I'm certain that this has been discussed already but I'm new to bash so I don't know what the jargon is to search yet. Thanks for any help.

2 Answers2

1

That doesn't work the way you expect it because of the order of expansion.

From the bash manual:

The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and pathname expansion.

In your first line, the ~ would be expanded if used without the quotes. As it is, the ~ inside the quotes is not expanded, and it is not expanded later because tilde expansion is done before variable expansion.

You write that it appears to work, but the fact that the output of echo is ~/local/bin/newFile.sh shows that it does not work.

If you need quoted because the value contains spaces, you can quote the part after ~/:

mypath=~/"local/bin with spaces/"
newFile="${mypath}newFile.sh"
echo "$newFile"
RalfFriedl
  • 8,981
0

Obviously, I figured out the answer instantly.

$ newFile="${mypath}newFile.sh"
touch newFile

doesn't work

$ newFile=${mypath}newFile.sh
touch newFile

does work

  • Both of your commands touches newFile (literal name). You probably meant touch $newFile. That would break as soon as $mypath contains a whitespace character. The real issue is the expansion of the tilde, which does not happen in quotes. Use $HOME instead. – Kusalananda May 23 '19 at 16:34