{"id":13602861,"url":"https://github.com/bashup/dotenv","last_synced_at":"2025-07-14T16:31:51.558Z","repository":{"id":108853768,"uuid":"141923304","full_name":"bashup/dotenv","owner":"bashup","description":"Programmatically parse/read/edit .env files (docker-compose format)","archived":false,"fork":false,"pushed_at":"2019-09-18T03:49:46.000Z","size":13,"stargazers_count":122,"open_issues_count":1,"forks_count":11,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-07T06:40:21.560Z","etag":null,"topics":["bash","bash-scripting","docker-compose","dotenv-editor","dotenv-parser"],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc0-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bashup.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-07-22T19:08:49.000Z","updated_at":"2024-10-05T00:27:58.000Z","dependencies_parsed_at":"2023-03-22T01:32:13.807Z","dependency_job_id":null,"html_url":"https://github.com/bashup/dotenv","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bashup%2Fdotenv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bashup%2Fdotenv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bashup%2Fdotenv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bashup%2Fdotenv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bashup","download_url":"https://codeload.github.com/bashup/dotenv/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225986603,"owners_count":17555661,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bash","bash-scripting","docker-compose","dotenv-editor","dotenv-parser"],"created_at":"2024-08-01T18:01:40.890Z","updated_at":"2024-11-23T01:18:41.684Z","avatar_url":"https://github.com/bashup.png","language":"Shell","funding_links":[],"categories":["bash","Shell"],"sub_categories":[],"readme":"# dotenv: read and edit .env files from bash\n\n.env files are a handy convention for configuring applications (especially with docker-compose).  But when you're writing shell scripts, it can be hard to modify or parse them.  (Especially the ones in [docker-compose format](https://docs.docker.com/compose/compose-file/#env_file)!)\n\n`dotenv` is a tiny bash scripting tool for manipulating `.env` files formatted like this:\n\n```ini\n# Lines are comments OR key=value pairs; leading and\n# trailing whitespace is stripped\n  FOO=bar\n\n# Everything after the '=' is taken EXACTLY AS-IS (except for\n# trailing whitespace removal), so the following line sets BAR\n# to \"baz \\\"blah # foo\".\nBAR=baz \"blah # foo\n```\n\nThis format is exactly how docker-compose parses `.env` and `env_files`, so this lets you easily read and write them, without losing comments, changing indentation, or moving/rearranging existing variables.\n\n(Note: if you need to read or write `.env` files that *aren't* in docker-compose syntax (e.g. shell dotfiles), you'll have to escape the values you write and unescape the ones you read, using whatever syntax is compatible with the other tools using the file.  Also, multi-line values can't be used unless the other tools can encode encode/decode linefeeds in such a way that the encoded form doesn't contain any actual linefeeds.)\n\n**Contents**\n\n\u003c!-- toc --\u003e\n\n- [Installation, Requirements And Use](#installation-requirements-and-use)\n  * [The `dotenv` CLI](#the-dotenv-cli)\n  * [The `.env` shell function](#the-env-shell-function)\n  * [File Selection](#file-selection)\n    + [`-f` | `--file` *filename*](#-f----file-filename)\n  * [Read Operations](#read-operations)\n    + [`get` *key*](#get-key)\n    + [`parse` *[keys...]*](#parse-keys)\n    + [`export` *[keys...]*](#export-keys)\n  * [Write Operations](#write-operations)\n    + [`set` [+]*key*[=*value*]...](#set-keyvalue)\n    + [`puts` *string*](#puts-string)\n    + [`generate` *key command [args...]*](#generate-key-command-args)\n- [License](#license)\n\n\u003c!-- tocstop --\u003e\n\n## Installation, Requirements And Use\n\nTo install dotenv, you can copy and paste the [code](dotenv) into your script, or download it, `chmod +x` it and save it somewhere on your `PATH`.  (if you have [basher](https://github.com/basherpm/basher), you can `basher install bashup/dotenv` to automatically install it.)\n\nThe code is licensed CC0, so you are not required to add any attribution or copyright notices to your project.  The only external commands it uses are `cp -p` and `mv`, and it's compatible with bash 3.2+, so it should work even on plain OS X, busybox, or pretty much anything else that can run bash.\n\nOnce you've got it installed, there are two ways you can use it: as a command line tool (`dotenv`), or a bash function (`.env`).\n\n### The `dotenv` CLI\n\nTo interactively manipulate .env files, you can run `dotenv` as a command line tool, e.g.:\n\n```console\n    $ dotenv --help\n    Usage:\n      dotenv [-f|--file FILE] COMMAND [ARGS...]\n      dotenv -h|--help\n    \n    Options:\n      -f, --file FILE          Use a file other than .env\n    \n    Read Commands:\n      get KEY                  Get raw value of KEY (or fail)\n      parse [KEY...]           Get trimmed KEY=VALUE lines for named keys (or all)\n      export [KEY...]          Export the named keys (or all) in shell format\n    \n    Write Commands:\n      set [+]KEY[=VALUE]...    Set or unset values (in-place w/.bak); + sets default\n      puts STRING              Append STRING to the end of the file\n      generate KEY [CMD...]    Set KEY to the output of CMD unless it already exists;\n                               return the new or existing value.\n\n    $ echo '  # This is my .env file' \u003eprod.env\n    $ echo '  FOO=bar  ' \u003e\u003eprod.env\n\n    $ cat prod.env\n      # This is my .env file\n      FOO=bar  \n\n    $ dotenv -f prod.env get FOO\n    bar\n```\n\n### The `.env` shell function\n\nTo manipulate .env files from within a shell script, you can source `dotenv` and then use the `.env` shell function.  The key differences are that:\n\n* `.env` keeps the last `.env` or `--file` contents in memory for faster reads  (using `--file` again will force a reload)\n* `.env` returns results in the bash `$REPLY` variable rather than writing them to standard output, and\n* the `export` subcommand actually sets and exports shell variables, rather than outputting `export` commands\n\n```sh\n# Source to get the .env function:\n\n    $ source dotenv\n\n# It takes the same arguments as `dotenv`:\n\n    $ .env --file prod.env get FOO\n\n# But output is to the REPLY variable instead of stdout:\n\n    $ echo \"$REPLY\"\n    bar\n\n# And the selected --file is \"sticky\" from one call to the next:\n\n    $ .env set FOO=wat BAR=baz  # still using --file prod.env\n\n    $ cat prod.env\n      # This is my .env file\n      FOO=wat\n    BAR=baz\n```\n\n### File Selection\n\n#### `-f` | `--file` *filename*\n\nBy default, all operations read or write to `.env` in the current directory at the time of the operation.  Using this option changes the active file to *filename*, and loads its current contents.  The in-memory contents are then used for any subsequent operations other than `set` (which reloads the file before making any changes).\n\nA non-existent file is silently considered to be empty; file read errors result in a failure return.\n\n### Read Operations\n\nThe following operations return their result in `REPLY` (or `REPLY[@]` for multiple results) when called via the `.env` shell function, or output one or more lines to stdout when invoked via the `dotenv` command.  Success is returned if there is at least one result, failure otherwise.\n\n#### `get` *key*\n\nRetrieve the value of *key* from the in-memory file.  Returns success if the key is found, failure otherwise.\n\n```sh\n    $ .env get FOO \u0026\u0026 echo \"$REPLY\"\n    wat\n\n    $ .env get BAZ || echo \"no such key\"\n    no such key\n```\n\n#### `parse` *[keys...]*\n\nReturn the parsed `KEY=value` pairs from the in-memory file, trimming whitespace and skipping blank lines and comments.  If *keys* are given, only return lines with matching keys (in their in-file order).  If no suitable lines are found, return failure.\n\n```sh\n# .env returns results as an array in REPLY:\n\n    $ .env parse\n    $ printf '%s\\n' \"${REPLY[@]}\"\n    FOO=wat\n    BAR=baz\n\n# Restricted to given keys, if any:\n\n    $ .env parse FLIM FOO FLAM; printf '%s\\n' \"${REPLY[@]}\"\n    FOO=wat\n\n# Returning failure if there are no matches:\n\n    $ .env parse FLIM FLAM || echo \"nothing found\"\n    nothing found\n```\n\n#### `export` *[keys...]*\n\nExport the values found in the file as environment variables (restricted to those named in *keys*, if given).  When used on the command line, output the key-value pairs in a format suitable for `eval`-ing.  Success is returned unless `export` fails due to invalid characters found in a key.\n\n```sh\n# dotenv export output is shell-escaped for correct eval-ing:\n\n    $ .env set FOO='bar baz' BING='bang; bong'\n\n    $ dotenv -f prod.env export\n    export FOO=bar\\ baz\n    export BAR=baz\n    export BING=bang\\;\\ bong\n\n# .env export just exports the variables (which can be filtered):\n\n    $ .env export BAR BING   # use -f to force reload from disk\n\n    $ declare -p BAR BING\n    declare -x BAR=\"baz\"\n    declare -x BING=\"bang; bong\"\n\n    $ declare -p FOO 2\u003e/dev/null || echo \"FOO not found\"\n    FOO not found\n\n    $ .env export  # export everything now\n\n    $ declare -p FOO\n    declare -x FOO=\"bar baz\"\n```\n\n### Write Operations\n\n#### `set` [+]*key*[=*value*]...\n\nEdit the .env file atomically in place, writing to a `.bak` file and then replacing the original.  (Like sed, this replaces a symlink with a regular file.  (Unless you're using it as a shell function and have also sourced [realpaths](https://github.com/bashup/realpaths), in which case the backup and overwrite are done in the symlinked directory.)\n\nEach argument passed must be match one of the following patterns:\n\n* `KEY=VALUE` sets `KEY` to `VALUE`; if the key previously existed, the line is edited in place, otherwise a new, unindented assignment is appended to the file.\n\n* `+KEY=VALUE` appends `KEY=VALUE` to the file unless there is an existing value for `KEY`:\n\n  ```sh\n    $ .env set +FLIM=\"flam\" +FOO=\"already set, won't change\"\n\n    $ dotenv -f prod.env export FLIM FOO\n    export FOO=bar\\ baz\n    export FLIM=flam\n  ```\n\n* An argument without an `=` is assumed to be a key that should be deleted from the file, removing any lines that set that key.\n\n  ```sh\n  # Unset keys if they exist:\n\n    $ .env set BING FOO FLIM\n\n    $ cat prod.env\n      # This is my .env file\n    BAR=baz\n  ```\n\n\nComment lines in the file are unchanged.  The file is reloaded from disk immediately before making the changes, and is only rewritten if the contents actually changed.  (That is, if you set values that already exist or delete values that don't, the file is not rewritten.)\n\n#### `puts` *string*\n\nAppend *string* to the .env file *and* its in-memory representation:\n\n```sh\n# Append some text:\n\n    $ .env puts '# A new comment'\n    $ .env puts 'FLIM=flam'\n\n# The file is updated in memory:\n\n    $ .env get FLIM \u0026\u0026 echo $REPLY\n    flam\n\n# And also on disk:\n\n    $ cat prod.env\n      # This is my .env file\n    BAR=baz\n    # A new comment\n    FLIM=flam\n```\n\n#### `generate` *key command [args...]*\n\nSets *key* to the output of running *command args...* unless there is an existing value for *key* (in which case *command* is not run).  The new (or existing) value of *key* is returned, and the result is a success unless *command* was run and failed.  With a suitable *command*, this can be used to generate default passwords, hash keys, etc.\n\n```sh\n    $ .env generate FLIM echo spam   # already exists, no change\n    $ echo $REPLY                    # returns old value\n    flam\n\n    $ .env generate FILE ls   # doesn't exist, so set it to \"$(ls)\"\n    $ echo $REPLY             # returns new value\n    prod.env\n\n    $ dotenv -f prod.env get FILE   # and it's updated on disk\n    prod.env\n```\n\n## License\n\n\u003cp xmlns:dct=\"http://purl.org/dc/terms/\" xmlns:vcard=\"http://www.w3.org/2001/vcard-rdf/3.0#\"\u003e\n  \u003ca rel=\"license\" href=\"http://creativecommons.org/publicdomain/zero/1.0/\"\u003e\u003cimg src=\"https://licensebuttons.net/p/zero/1.0/80x15.png\" style=\"border-style: none;\" alt=\"CC0\" /\u003e\u003c/a\u003e\u003cbr /\u003e\n  To the extent possible under law, \u003ca rel=\"dct:publisher\" href=\"https://github.com/pjeby\"\u003e\u003cspan property=\"dct:title\"\u003ePJ Eby\u003c/span\u003e\u003c/a\u003e\n  has waived all copyright and related or neighboring rights to \u003cspan property=\"dct:title\"\u003ebashup/realpaths\u003c/span\u003e.\nThis work is published from: \u003cspan property=\"vcard:Country\" datatype=\"dct:ISO3166\" content=\"US\" about=\"https://github.com/bashup/dotenv\"\u003eUnited States\u003c/span\u003e.\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbashup%2Fdotenv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbashup%2Fdotenv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbashup%2Fdotenv/lists"}