Skip to content

Latest commit

 

History

History
291 lines (186 loc) · 4.39 KB

specification.md

File metadata and controls

291 lines (186 loc) · 4.39 KB

POSIX-compliant .env syntax specification

POSIX-compliant .env syntax is subset of POSIX shell scripts

File format

The encoding is UTF-8

UTF-8 is already widespread and there is no need to support other encodings.

The newline code is LF only

POSIX shells treats CR as a character.

# when the newline code is CR LF
FOO=123
echo "${#FOO}" # => 4

The first line is a directive to distinguish between .env syntax dialects

# dotenv posix
FOO=123

Cannot contain null characters

The shell cannot handle the null (\0) character.

Environment variable name

The key must be followed by =

POSIX shell specification

Valid

FOO=

Invalid

FOO

Spaces or tabs can be inserted before the name

POSIX shell specification.

Valid

    FOO=123

No spaces or tabs around =

POSIX shell specification.

Invalid

FOO   =123
BAR=   123

The name must be [a-zA-Z_][a-zA-Z0-9_]*

POSIX shell specification.

Invalid

FOO.BAR.BAZ=123
1ABC=123

The name can have an export prefix

Many dotenv implementations support it.

Valid

export FOO=123
export BAR # Same as `export BAR="${BAR:-}"`

Comment

Lines beginning with # are comments

POSIX shell specification.

Valid

# comment
    # comment

Comment after the value must have spaces or tabs before the #

POSIX shell specification.

Valid

FOO=123 # this is comment
BAR='123' # this is comment
BAZ="123" # this is comment

Invalid

FOO=123#this-is-not-comment
BAR='123'#this-is-not-comment
BAZ="123"#this-is-not-comment

Unquoted value

Cannot contain spaces or tabs

POSIX shell specification.

Invalid

FOO=123 456

Some symbols cannot be used

The following characters have a special meaning in shell scripts and cannot be used without quotes.

[ ] { } ( ) < > " ' ` ! $ & ~ | ; \ * ?

In the POSIX shell specification, it can be used by escaping it with a backslash, but it is better to use quotes.

Invalid

URL=http://example.com?name1=value1&name2=value2

Note: # (without preceding spaces or tabs) can be used as a character.

Valid

URL1='http://example.com?name1=value1&name2=value2'
URL2=http://example.com/index.html#this-is-hash #this-is-comment

Variable expansion is not available

The behavior is different for different shells, so it is not portable.

VAR="foo bar"
export VALUE=$VAR
echo "$VALUE"
# => dash, posh, yash: `foo`
# => bash, ksh, mksh, zsh: `foo bar`

Single-quoted value

The value cannot contain single quotes

POSIX shell specification. Use double quotes.

Invalid

VAR1='foo'bar'
VAR2='foo\'bar'

Cannot use variable expansion

POSIX shell specification.

Invalid

VAR='${FOO}' # this is just a string

Newlines can be inserted

Valid

VAR='line1
line2'

Not possible to close quotes in the middle of a line

This is possible in POSIX shell specification, but prohibited for simplicity of the specification.

Invalid

VAR='foo''bar'

Double-quoted value

Escaping is required when using " ` \ $ as a value

POSIX shell specification.

Invalid

VAR=" " ` \ $ "

Valid

VAR=" \" \` \\ \$ "

Except for the above, backslashes are not escape characters

POSIX shell specification.

VAR=" \a \r \n "
printf '%s' "$VAR" # => \a \r \n

NOTE: Do not investigate with echo. In some shells, echo may interpret escape characters.

The \ at the end of the line means line continuation

POSIX shell specification.

LONGLINE="https://github.com/ko1nksm\
/shdotenv/blob/main/README.md"

echo "$LONGLINE" # => https://github.com/ko1nksm/shdotenv/blob/main/README.md

Variable expansion is supported

POSIX shell specification.

Valid

BAR="bar"
VALUE="foo ${BAR} baz"

Braces are required for variable expansion

If there are no braces, the behavior may vary depending on the shell.

BAR="bar"
VALUE="foo $BAR[0] baz"
# => bash: foo bar[0] baz
# => zsh: foo  baz

If the variable is not set, it treats as an empty string

POSIX shell specification

unset BAR
VALUE="foo ${BAR} baz"
echo "$VALUE" # => foo  baz

Command substitution is not supported

It is not supported due to its complexity and the security risk of random command execution.