theskumar / python-dotenv

Reads key-value pairs from a .env file and can set them as environment variables. It helps in developing applications following the 12-factor principles.
https://saurabh-kumar.com/python-dotenv/
BSD 3-Clause "New" or "Revised" License
7.32k stars 417 forks source link

Export multiline variable #518

Open aphilas opened 2 weeks ago

aphilas commented 2 weeks ago

The description for --export says "Whether to write the dot file as executable bash script."

However, if I used the --export flag with a multiline variable, the output cannot be correctly parsed by bash.

For example:

# .env
TEST_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDcRcBc/es9fD1s\nsvWIerF1c8BAqDbkoX9A1KF7uZLXTj90MEDoSAgZ6c8Q77A/DAZtIxS5ip6lG6RN\ncfz0JUrN9wQgjiFAUtvqfP74LXm7fG9iz8DUMoCBkQLsefVK2z/bG4Uul/fvTLjM\nPCef7jyertafr+x5F3QrGsAOC9pX28d40g1xW6JtLbQR6++4kfKtS7/D+WFdqqw7=\n-----END PRIVATE KEY-----\n"
$ dotenv -f ./.env -e 1 list
TEST_PRIVATE_KEY=-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDcRcBc/es9fD1s
svWIerF1c8BAqDbkoX9A1KF7uZLXTj90MEDoSAgZ6c8Q77A/DAZtIxS5ip6lG6RN
cfz0JUrN9wQgjiFAUtvqfP74LXm7fG9iz8DUMoCBkQLsefVK2z/bG4Uul/fvTLjM
PCef7jyertafr+x5F3QrGsAOC9pX28d40g1xW6JtLbQR6++4kfKtS7/D+WFdqqw7=
-----END PRIVATE KEY-----
$ eval $(dotenv -f ./.env -e 1 list)
bash: command not found: PRIVATE

Is this expected?

Alternatives workarounds I am aware of:

Bajron commented 1 week ago

I think the help message is indeed a little unfortunate. After browsing the code, it seems the --export or -e is used only during the set operation. It prefixes the variable with the export keyword.

To make you example work try providing --format shell or --format export to the list command. For example eval $(dotenv -f ./.env list --format shell)

Check out this short bash session to figure out what happens when:

# -e adds "export" during "set" operation
dotenv -e 1 set ML "1
2
3"

cat .env
bash -c 'source .env' # bash can handle the format

# simple list
dotenv list
# can be handled by shell
dotenv list --format shell
# can be handled by shell, exports variables
dotenv list --format export

# eval and echo
eval $(dotenv list --format shell)
echo ML: $ML

# eval and echo with changed IFS to see the newlines
OLDIFS=$IFS
IFS=:
eval $(dotenv list --format shell)
echo ML: $ML
IFS=$OLDIFS