4

There are a lot of examples here how to source a dotenv file in bash but has anyone one a method that achieves the same with dash (which is the default shell for minimal Debian installations)?

The solution should look like this:

$ some foo my-command-using-env-vars

e.g.

$ env $(cat .env) my-command-using-env-vars

And it is important that the solution supports multiline values with spaces like:

SSH_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nfoo\nbar\baz"

and special characters like hash within quotes:

SPECIAL="foo#bar"
Bastian Venthur
  • 12,515
  • 5
  • 44
  • 78

1 Answers1

4

It seems that your problem is not so much that you're using dash but that you want to support \n escapes. The following works in dash and supports \n escapes:

eval "$(echo $(cat .env))" my-command-using-env-vars

That's because unlike in bash the built-in echo in dash supports backslash escapes even without the -e option. The following works in both bash and dash, provided that the non-built-in, system echo supports the -e option:

eval "$(env echo -e $(cat .env))" my-command-using-env-vars

Note that both approaches will also handle other backslash escapes (either POSIX or GNU), possibly in a different way than you expect.

Some technical notes:

$(cat .env)

performs Field Splitting, converting any newline in file .env into spaces.

"$(env echo -e ...)"

expands backslash escapes regardless of the current shell by invoking echo -e via env. The double quotes disable field splitting, so that newlines are preserved.

nwellnhof
  • 32,319
  • 7
  • 89
  • 113
  • Thanks for the solution! Just for the curious, how exactly will the other backslash escapes be handled in the above cases? – Bastian Venthur Aug 14 '17 at 07:17
  • @BastianVenthur Have a look at the `dash` and `bash` man pages and search for builtin commands. For `env echo`, see the `echo` man page. – nwellnhof Aug 14 '17 at 11:27
  • `echo` is fine when using your shell interactively, but you shouldn't use it in scripts which need to be portable, as its behaviour is variable across different systems. Conversely `printf` is very portable and standardised, so it's good practice to be using that instead. – phils Jun 05 '19 at 09:33