Note: This general topic seems to be covered ad nauseum on more than one SE site, but please read through all the details — I don't find any questions which cover all the criteria described below.
Also: I'm using
zsh
in the examples below. I'm hoping for a POSIX-compliant solution, but that's not a hard requirement: something that works forbash
andzsh
is good enough.
Here's an example to help clarify the question title:
Let's say I have the following two files:
% ls -AF
.env printenv*
% cat printenv
echo $LOCAL_MESSAGE_1
echo $LOCAL_MESSAGE_2
% cat .env
LOCAL_MESSAGE_1="hello world"
LOCAL_MESSAGE_2="goodnight moon"
and I'd like to execute the script printenv
and see the following in stdout
:
hello world
goodnight moon
If those variables don't exist in my environment, the script prints empty lines (as expected):
% unset LOCAL_MESSAGE_1
% unset LOCAL_MESSAGE_2
% ./printenv
If I set the variables before executing the script, they become available to it, but only for that single process, and not to any subsequent processes launched from the same shell:
% LOCAL_MESSAGE_1="hello world" LOCAL_MESSAGE_2="goodnight moon" ./printenv
hello world
goodnight moon
% ./printenv
So, my question is this: How can I replicate the behavior in the last example according to the following criteria?
- run
printenv
without modification in the current shell — not in a subshell (thanks RudiC) — and get the desired output, while also - loading the variables from the
.env
file, while also - keeping the variables local to that process invocation: they will remain unset in the shell environment and to subsequent processes without needing to
unset
them
What single line syntax can I use to accomplish this? What should be substituted in place of the question marks below to meet the criteria above?
% ?????????? ./printenv
hello world
goodnight moon