Home / Alt manpages / python-dotenv(1)

  • python-dotenv(1)
  • User command
  • linux

Edit and Test .env Files Safely with python-dotenv

You will create a small .env file, inspect its values, run one command with those values in its environment, and remove a key without opening the file in an editor. The examples use python-dotenv 1.0.1 from Debian package python3-dotenv 1.0.1-1. Allow about ten minutes. You need a shell and a writable working directory; none of these operations normally needs elevated privileges.

A .env file can contain passwords, tokens and connection strings. Treat it as sensitive configuration: do not paste its contents into a ticket, commit it to a public repository, or use list in a shared terminal where its output can be captured.

1. Confirm the installed command

Check the executable and version before relying on an example. This is read-only:

$ command -v python-dotenv
/usr/bin/python-dotenv
$ python-dotenv --version
python-dotenv, version 1.0.1
$ dpkg-query -W -f='${Package} ${Version}\n' python3-dotenv
python3-dotenv 1.0.1-1

The command edits the file selected by -f or --file. If you omit that option, it uses .env in the current working directory. Check your directory before changing anything:

$ pwd
/home/alex/demo
$ test -e .env && echo 'an existing .env will be changed' || echo 'no .env yet'
no .env yet

Checkpoint: if an existing file contains useful or secret values, copy it to a protected backup before using set or unset. Do not put the backup in a shared directory.

2. Add values with set

Store two harmless example values. Replace them with your application's names and values, but keep real secrets out of shell history where possible:

$ python-dotenv set APP_MODE development
APP_MODE=development
$ python-dotenv set API_URL 'https://api.example.test/v1'
API_URL=https://api.example.test/v1

With the default --quote always mode, the command writes quoted values even though it displays the value without those quotes:

$ sed -n l .env
APP_MODE='development'$
API_URL='https://api.example.test/v1'$

The quoting option affects how values are written, not how python-dotenv parses them. --quote never writes unquoted values, while --quote auto quotes only when needed. The command's top-level options must appear before the subcommand:

$ python-dotenv --file settings.env --quote never set LOG_LEVEL info
LOG_LEVEL=info
$ sed -n l settings.env
LOG_LEVEL=info$

Do not use > to edit a file by hand unless you understand the overwrite. The set command is easier to review because it targets one key. If you wrote the wrong value, run set again with the same key and the corrected value.

3. Inspect one key or the whole file

Use get when you need one value, and list when you need to review all stored key-value pairs:

$ python-dotenv get APP_MODE
development
$ python-dotenv list
API_URL=https://api.example.test/v1
APP_MODE=development

The list order is not a useful configuration contract, so do not build a script that depends on it. A missing key produces no output and returns status 1 on the installed command:

$ python-dotenv get NOT_DEFINED
$ printf 'status: %s\n' "$?"
status: 1

Checkpoint: use the status immediately after get. A later command replaces $?, and an empty value is not the same as a successful lookup of a key whose value happens to be empty.

4. Run a command with the file loaded

run starts the command after the file values have been added to its environment. Put -- before the child command so its arguments are visually separate from python-dotenv options:

$ python-dotenv run -- sh -c 'printf "APP_MODE=%s\nAPI_URL=%s\n" "$APP_MODE" "$API_URL"'
APP_MODE=development
API_URL=https://api.example.test/v1

The child inherits the rest of your existing environment. Do not assume that run is a secret manager: the child process can read the values, and a verbose application can print them. Use a deliberately small diagnostic command while testing. This operation changes no persistent file and ends when the child exits.

Check the child command's status when it matters:

$ python-dotenv run -- sh -c 'test "$APP_MODE" = development'
$ printf 'child status: %s\n' "$?"
child status: 0

5. Remove a key, then verify it

unset removes the named key from the selected file. This changes persistent configuration, so pause before running it against a production file:

$ python-dotenv unset API_URL
Successfully removed API_URL
$ python-dotenv get API_URL
$ printf 'lookup status: %s\n' "$?"
lookup status: 1
$ python-dotenv list
APP_MODE=development

There is no undo subcommand. To recover, restore your protected backup or add the key again with set. If the file is shared by an application, make the change during its normal configuration window and restart or reload it only according to that application's own instructions. python-dotenv does not restart services.

6. Choose export mode only for shell-style consumers

The --export option writes the file as an executable Bash-style script by prefixing assignments with export. It is a file-format choice, not a permission escalation:

$ python-dotenv --file shell.env --export true --quote never set APP_MODE development
APP_MODE=development
$ sed -n l shell.env
export APP_MODE=development$

Use this only when the program consuming the file expects shell assignments. Python-dotenv's parser does not require the export word, so do not enable the option merely because the file is called .env. Review the resulting file before sourcing it. Sourcing a file executes shell syntax, which is a different and more security-sensitive operation from reading key-value pairs.

7. Use a separate file when the default is distracting

Multiple environments are easier to keep apart when each command names its file explicitly:

$ python-dotenv --file .env.test set APP_MODE test
APP_MODE=test
$ python-dotenv --file .env.test run -- sh -c 'printf "%s\n" "$APP_MODE"'
test

This avoids accidentally editing the .env in whichever directory your shell happens to use. The path is resolved by the command, so use an absolute path when a script may run from an unpredictable working directory. Keep permissions and ownership appropriate for the account that needs the values. sudo is not a normal requirement; use it only if the file or directory is intentionally restricted, and verify the target path first.

Done means

  • You confirmed the installed python-dotenv version and selected the intended file.
  • set, get and list produced the values you expected.
  • run -- passed configuration to a test command without changing the file.
  • You checked exit status 1 separately from an empty or missing value.
  • You backed up persistent configuration before using unset and know how to restore it.
  • Secrets remain out of shared output, shell history where practical, and public repositories.