T Anna
T Anna

Reputation: 1004

Set the value of a local variable equal to an env variable

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

Answers (2)

chepner
chepner

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

that other guy
that other guy

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

Related Questions