Reputation: 1004
I have the below two files :
1) env-vars.sh
export MY_DATABASE=postgres
2) my-test.sh
#!/bin/bash
. $(pwd)/env-vars.sh
echo $MY_DATABASE
cat > $(pwd)/conf/my-vars.conf <<- "EOF"
MY_DATABASE=$MY_DATABASE
EOF
Now my second script is echoing the env variable in the env-vars.sh file properly and even creating the my-vars.conf file but the contents of this file are as below:
MY_DATABASE=$MY_DATABASE
I want the file my-vars.conf to have the value of the variable MY_DATABASE as postgres. How do I assign the env variable value?
Upvotes: 1
Views: 1757
Reputation: 531265
To do this correctly, you need some additional support from your shell. Assuming you are using bash
, you should use the following:
printf 'MY_DATABASE=%q\n' "$MY_DATABASE" >> conf/my-vars.conf
The reason you need %q
for this is to guard against a value of MY_DATABASE
that doesn't allow simple interpolation to produce code that reproduces the value. Some examples:
$ MY_DATABASE="foo bar"
$ printf 'MY_DATABASE=%s\n' "$MY_DATABASE"
MY_DATABASE=foo bar
$ printf 'MY_DATABASE=%q\n' "$MY_DATABASE"
MY_DATABASE=foo\ bar
This might lead you to think you can just add quotes to the output. Wrong.
$ MY_DATABASE='foo" bar'
$ printf 'MY_DATABASE="%s"\n' "$MY_DATABASE"
MY_DATABASE="foo" bar"
$ printf 'MY_DATABASE=%q\n' "$MY_DATABASE"
MY_DATABASE=foo\"\ bar
It's better to write code that can't produce bad output than to write simpler code that relies on well-formed input.
If you need to combine printf
with an additional cat
command, the printf
does not go inside the here document; both cat
and print
should write to the same output file.
printf 'MY_DATABASE=%q\n' "$MY_DATABASE" > conf/my-vars.conf
cat >> conf/my-vars.conf <<- "EOF"
SOME_OTHER_VAR="a different value"
EOF
Better yet, put both printf
and cat
inside a command group that shares a single output redirection.
{
printf 'MY_DATABASE=%q\n' "$MY_DATABASE"
cat <<- "EOF"
SOME_OTHER_VAR="a different value"
EOF
} > conf/my-vars.conf
Upvotes: 0
Reputation: 123480
You can control expansion with the quotes around the here document token:
# Shows "Hello, $(whoami)"
cat << "EOF"
Hello, $(whoami)
EOF
# Shows "Hello, myuser"
cat << EOF
Hello, $(whoami)
EOF
So just unquote EOF
in your script.
Upvotes: 2