shdotenv

repository·main·Indexed 43 days ago

https://github.com/ko1nksm/shdotenv

A shell-based tool for safely loading .env files into shell environments. It supports multiple dialects including POSIX, Docker, Node, Python, Ruby, PHP, Go, and Rust, allowing users to execute commands with environment variables or load them into sessions via eval without the security risks of direct sourcing.

Tokens
4.1K
Snippets
17
Records
19
Agent score
54%

What's inside shdotenv

  1. Use double-quoted values for expansion and escaping

    main

    Double quotes (") provide more flexibility for complex values:

    • Variable Expansion: Supports ${VAR} syntax. It is recommended to use braces (e.g., ${BAR}) to ensure consistent behavior across different shells.
    • Escaping: You must escape backslashes (\), backticks (`), and dollar signs ($) using a backslash.
    • Line Continuation: A backslash (\) at the very end of a line allows you to continue the value on the next line.
    • No Command Substitution: For security reasons, command substitution (e.g., $(command)) is not supported.
    • Backslashes: Outside of escaping the specific characters mentioned above, backslashes are treated as literal characters.

    Valid Examples:

    # Variable expansion
    BAR="bar"
    VALUE="foo ${BAR} baz"
    
    # Escaping
    VAR=" \" \` \\ \$ "
    
    # Line continuation
    LONGLINE="https://github.com/ko1nksm\
    /shdotenv/README.md"

    Invalid Examples:

    VAR=" " ` \ $ "
    VAR="$(whoami)"
    BAR="bar"
    VALUE="foo ${BAR} baz"
  2. POSIX-compliant .env file syntax

    main

    The default syntax for shdotenv is a subset of POSIX shell.

    Key Syntax Rules:

    • Directives: The first line can be # dotenv <DIALECT> to specify a non-POSIX dialect.
    • Assignment: No spaces are allowed before or after the = sign.
    • Unquoted values: Only specific characters (# % + , - . / : = @ ^ _) are allowed. # starts a comment if preceded by a space.
    • Single-quoted values: Can contain newlines; cannot contain '.
    • Double-quoted values: Supports variable expansion using ${VAR}. Escapable characters: $, ", and \. A \ at the end of a line allows line continuation.
    • Comments: End-of-line comments must be preceded by a space before the # character.
    # dotenv posix
    COMMENT=This-#-is-a-character # This is a comment
    
    UNQUOTED=value1
    SINGLE_QUOTED='value 2'
    DOUBLE_QUOTED="value 3"
    
    MULTILINE="line1
    line2: \n is not a newline
    line3"
    
    ENDPOINT="http://${HOST}/api"
    
    export EXPORT1="value"
  3. Use single-quoted values for literal strings

    main

    Single quotes (') are used to define literal strings.

    • No Expansion: Variable expansion is not supported; ${VAR} will be treated as a literal string.
    • No Nested Quotes: You cannot include a single quote inside a single-quoted value. Use double quotes instead.
    • Newlines: You can include literal newlines within single quotes.
    • No Mid-line Closing: You cannot close a quote and start a new one on the same line (e.g., 'foo''bar' is invalid).

    Valid Example:

    VAR='line1
    line2'

    Invalid Examples:

    VAR1='foo'bar'
    VAR='${FOO}'
    VAR='line1
    line2'
  4. Use unquoted values for simple strings

    main

    Unquoted values are suitable for simple strings but have strict limitations:

    • No Spaces: Values cannot contain spaces or tabs.
    • Special Characters: Certain symbols require quotes because they have special meaning in shell scripts: [ ] { } ( ) < > " ' ! $ & ~ | ; \ * ? =`.
    • No Expansion: Variable expansion (e.g., ${VAR}) is not supported in unquoted values.

    Valid Example:

    FOO=123

    Invalid Examples:

    FOO=123 456
    URL=http://example.com?name1=value1&name2=value2
    FOO=123
  5. Format .env files using POSIX-compliant syntax

    main

    To ensure compatibility with shdotenv, format your .env files following the POSIX-compliant subset of shell scripts.

    File Encoding and Newlines

    • Encoding: Use UTF-8.
    • Newlines: Use LF (Line Feed) only. Using CR LF will cause the carriage return (`

    `) to be treated as part of the variable value, increasing its length.

    • Null Characters: Files must not contain null (\0) characters.

    Syntax Dialect Directive

    To explicitly distinguish the file as using the POSIX dialect, include this directive as the first line:

    # dotenv posix
    # dotenv posix
    FOO=123
  6. Install shdotenv

    main

    You can install shdotenv by downloading the shell script from the official releases. It is recommended to place it in a directory included in your PATH, such as $HOME/bin or $HOME/.local/bin (following XDG Base Directory Specification).

    $ mkdir -p "$HOME/bin"
    $ wget https://github.com/ko1nksm/shdotenv/releases/latest/download/shdotenv -O "$HOME/bin/shdotenv"
    $ chmod +x "$HOME/bin/shdotenv"
  7. How to work with Docker and newlines

    main

    The docker run --env-file option does not support environment variables containing newlines. You can bypass this limitation using shdotenv to generate the -e flags for the docker command.

    shdotenv docker run $(shdotenv -n | sed s/^/-e/) debian sh -c export
  8. Best practices for .env files

    main

    When using shdotenv, follow these security and architectural best practices:

    • Do not commit .env files: Never commit your .env file to version control. It should only contain environment-specific secrets like database passwords or API keys.
    • Avoid using .env in production: Following the 12-factor app methodology, configuration should be stored in environment variables. While .env files are highly useful for local development convenience, using them in production is considered an anti-pattern.
    • Maintain orthogonality: Avoid defining the same variable name across different .env files unless you intend to use the --overload flag, as variables should ideally be granular and independent.
  9. Use shdotenv as a library in shell scripts

    main

    To load .env variables directly into your current shell session, use eval with the output of shdotenv. The syntax varies depending on your shell:

    POSIX-compliant shells (sh, bash, ksh, zsh)

    eval "$(shdotenv [OPTION]...)"

    To abort the script if the .env file fails to parse:

    eval "$(shdotenv [OPTION]... || echo "exit $?")"

    csh, tcsh

    set newline='\'
    eval "`shdotenv -f csh [OPTION]...`"

    fish

    eval (shdotenv -f fish [OPTION]...)
  10. Use shdotenv as a CLI utility

    main

    Use shdotenv to load .env files and execute a specific command with those environment variables set.

    To test if a .env file is syntactically correct without executing anything, use the --quiet flag.

    # Execute a command with .env variables
    shdotenv [OPTION]... <COMMAND> [ARGUMENTS]...
    
    # Test the .env file syntax
    shdotenv --quiet --env .env
  11. Export environment variables safely

    main

    The export subcommand allows you to list or export environment variables from a .env file. It is similar to the standard export, env, or printenv commands but ensures correct quoting and only exports portable variable names valid for POSIX shells.

    shdotenv [OPTION]... export [OPTION]... [NAME]...
  12. Define environment variable names and keys

    main

    When defining variables in a .env file:

    • Naming Convention: Names must follow the pattern [a-zA-Z_][a-zA-Z0-9_]* (start with a letter or underscore, followed by letters, numbers, or underscores).
    • Key Assignment: The key must be followed immediately by =.
    • Spacing:
      • Spaces or tabs can be inserted before the variable name.
      • Spaces or tabs cannot be inserted around the = sign.
    • Export Prefix: You may use the export prefix to define variables.

    Valid Examples:

        FOO=123
    export BAR=123
    export BAZ

    Invalid Examples:

    FOO
    FOO =123
    BAR= 123
    1ABC=123
    FOO.BAR=123
    # Valid
        FOO=123
    export BAR=123
    
    # Invalid
    FOO =123
    BAR= 123
    1ABC=123