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
user3142695
  • 1,599

1 Answers1

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" ]
  • 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? – user3142695 Oct 04 '17 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). – Kamil Maciorowski Oct 04 '17 at 21:54