22

How do I use variables in a filename correctly? This is what I'm doing, but it seems the underline makes some problems:

domain="example"
sub="foo"

if [ -f /opt/nginx/conf.d/com_$domain_$sub.conf ]
  cat <<EOF > /opt/nginx/conf.d/com_$domain_$sub.conf
some multiline
content
EOF
fi
4
  • Have you tried quoting it? Always double quote your variables.
    – jesse_b
    Commented Oct 4, 2017 at 21:41
  • I've quoted the complete path... Commented Oct 4, 2017 at 21:41
  • Related: $VAR vs ${VAR} and to quote or not to quote Commented Oct 4, 2017 at 21:51
  • 3
    If you stop deleting your questions as soon as someone comments with the correct answer, you might just have someone help you with sorting this program out. You've done that at least twice today. That syntax error question: there were other thing wrong in the code that could have been fixed and made more efficient, but that's impossible get to now, because you deleted the question as soon as someone told you what the syntax error was due to.
    – Kusalananda
    Commented Oct 4, 2017 at 21:56

1 Answer 1

34

In this case Bash interprets domain_ as the name of the variable to expand. It's a valid name for a variable. Expanding this name is not what you intended. You need to tell Bash where the intended name ends. Do it with ${}; in this case ${domain}, like this:

/opt/nginx/conf.d/com_${domain}_${sub}.conf

Here I used ${sub} even though $sub.conf cannot be misinterpreted (because . is not allowed in names of shell variables); I wanted to show you that using ${} where it's not necessary is still fine.

When your shell treated domain_ as the name, the variable expanded to an empty string. This variable had never been declared, yet it formally expanded successfully. Using an unset variable is normally not an error. Invoke set -u and Bash will treat unset variables as errors (revert with set +u if needed).

Treating unset variables as errors is useful for debugging, but also in defensive scripting. Unless you deliberately want to allow unset variables, it's often better for a script to fail immediately when it tries to expand an unset variable, than to continue and to work with the wrong value. When using variables to specify pathnames "wrong value" may mean "wrong file to overwrite or delete".

Also remember to quote right. The values in your example are safe when unquoted, still it's good to get used to quoting. IMO quoting habitually is easier and less error-prone than analyzing each time if you can get away without quotes.

if [ -f "/opt/nginx/conf.d/com_${domain}_$sub.conf" ]
2
  • That's working. But I do get a permission denied error for the cat command. Do I have to change chmod of the conf.d directory? Commented Oct 4, 2017 at 21:49
  • 1
    @user3142695 Probably; or run the script as different user. I don't know what you are trying to do exactly; nor what the permissions are etc. Before you give this information here please note this is not the right place. One problem, one question. "Permission denied" is a different problem. You may ask another question (but do your own research first). Commented Oct 4, 2017 at 21:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .