python-dotenv icon indicating copy to clipboard operation
python-dotenv copied to clipboard

Export multiline variable

Open aphilas opened this issue 1 year ago • 1 comments

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:

  • base64 encode/decode the env variable value

aphilas avatar Jun 24 '24 13:06 aphilas

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

Bajron avatar Jul 01 '24 19:07 Bajron

Thank you!

I must've not taken enough time to read help. Just checked dotenv --help. dotenv list --help would have clarified this (unless it's new).

$ dotenv --help
Usage: dotenv [OPTIONS] COMMAND [ARGS]...

  This script is used to set, get or unset values from a .env file.

Options:
  -f, --file PATH                 Location of the .env file, defaults to
                                  .env file in current working directory.
  -q, --quote [always|never|auto]
                                  Whether to quote or not the variable
                                  values. Default mode is always. This does
                                  not affect parsing.
  -e, --export BOOLEAN            Whether to write the dot file as an
                                  executable bash script.
  --version                       Show the version and exit.
  --help                          Show this message and exit.

Commands:
  get    Retrieve the value for the given key.
  list   Display all the stored key/value.
  run    Run command with environment variables present.
  set    Store the given key/value.
  unset  Removes the given key.
$ dotenv list --help
Usage: dotenv list [OPTIONS]

  Display all the stored key/value.

Options:
  --format [simple|json|shell|export]
                                  The format in which to display the list.
                                  Default format is simple, which displays
                                  name=value without quotes.
  --help                          Show this message and exit.

aphilas avatar Sep 23 '24 15:09 aphilas