12

I have a script that begin like this

#!/bin/bash
VALKYRIE=~/myProjects/valkyrie
source $VALKYRIE/cluster.conf

but when I run it it returns line 2: ~/myProjects/valkyrie/cluster.conf: No such file or directory

but the file exist and when I run source ~/myProjects/valkyrie/cluster.conf it runs fine. Any idea? I set VALKYRIE variable elsewhere so hard-code in the path isn't an option.

Khoi
  • 223
  • I'm not 100% sure if this will help, but you could try fully quoting the variable, in case there are spaces in ~. Hence, source "${VALKYRIE}/cluster.conf". – Sparhawk Jun 01 '13 at 03:41
  • no, it doesn't help. – Khoi Jun 01 '13 at 03:47
  • Are you saying that running source ~/myProjects/valkyrie/cluster.conf works, when you replace the last two lines of the script? (Or from the command line?) – Sparhawk Jun 01 '13 at 03:52
  • it works whether from command line or in the script – Khoi Jun 01 '13 at 03:54
  • 1
    I think it's something to do with ~ not expanding properly. When I run your script with an intentionally fake path, the error doesn't say ~, but expands the path. Can you try replacing the ~ in your script with the absolute path? Also, try running the following in a script echo ~. – Sparhawk Jun 01 '13 at 04:04
  • you're right, not using ~ did the trick. Thanks a lot! – Khoi Jun 01 '13 at 04:10
  • Is that good enough? Should I write it up as an answer, or do you want to use ~ and work out why it doesn't work? – Sparhawk Jun 01 '13 at 04:12
  • 2
    You could also try $HOME instead of ~. – Sparhawk Jun 01 '13 at 04:16
  • The code you show doesn't match the error message. You must have written VALKYRIE="~/myProjects/valkyrie" -- quotes would suppress the expansion of the tilde. – glenn jackman Jun 01 '13 at 04:40
  • to be exact I used VALKYRIE=~/myProjects/valkyrie without quotes inside ~/.pam_environment – Khoi Jun 01 '13 at 07:15
  • 4
    @Khoi That explains it. ~/.pam_environment is not a shell script, so it doesn't do the common things you'd expect from a shell, such as tilde expansion and parameter expansion, so neither ~ nor $HOME will be replaced. If you move that line to ~/.profile instead, and add export in front, it should work. – geirha Jun 01 '13 at 08:41
  • It's said that the recommended way to add environment variable is through ~/.pam_environment. Well I don't need to use ~ nor $HOME, works for me. – Khoi Jun 01 '13 at 09:24

1 Answers1

10

~ doesn't appear to be expanding properly. When I run your script with an intentionally fake path, the error doesn't say ~, but expands the path (i.e. /home/sparhawk/fakepath not ~/fakepath. You could try using $HOME instead of ~, or using the full path in the script instead.

(I'm not sure why ~ doesn't work on your system, as your script works fine for me.)

Sparhawk
  • 6,989
  • When you look at the order that bash performs expansions (http://www.gnu.org/software/bash/manual/bashref.html#Shell-Expansions), you'll see that tilde expansion happens before variable expansion. That's why $HOME is better than ~ in a variable – glenn jackman Jun 01 '13 at 04:29
  • @glennjackman I'm not sure I understand. Why would priority matter for variables vs. ~? – Sparhawk Jun 01 '13 at 04:33
  • 1
    it's not exactly "priority", it's simply what comes first. Consider x="~/.bashrc"; ls $x -- in the order of expansions for the "ls" command, bash looks for a tilde and doesn't find one; eventually bash sees a variable and expands it. bash does not go back and look for tildes again, at this point it's just a plain character. and there are no files in the current directory that begin with a tilde. – glenn jackman Jun 01 '13 at 04:41
  • Ah okay. I think I get it. I've always wondered why that command fails and x=~/".bashrc"; ls $x works. Thanks for the info. – Sparhawk Jun 01 '13 at 04:43
  • My path was within the quotes so I had to remove the quotes and it worked. – nick-s Oct 05 '22 at 02:56