When working with environment variables in development workflows, many developers find themselves needing a simple way to:
- Load variables from a .env file
- Inject them into a command's environment
- Execute the command without additional overhead
While tools like Foreman provide this functionality, they come bundled with many features (like Procfile processing) that aren't always needed.
The Unix philosophy favors small, focused tools. Here are several approaches:
1. Using env with xargs
cat vars.env | xargs -0 /bin/sh -c 'exec "$@"' -- myprogram arg1 arg2
2. Simple Bash Function
Add this to your ~/.bashrc:
runenv() {
set -o allexport
source $1
set +o allexport
shift
eval "$@"
}
Usage:
runenv vars.env myprogram --option value
3. Dedicated Tools
For those preferring standalone binaries:
- envconsul - Also handles Consul integration
- direnv - For directory-local environments
- dotenv - Node.js implementation (npm install -g dotenv-cli)
Here's how to chain multiple environment files with command substitution:
env -i bash -c 'source dev.env && source secrets.env && exec ./start_server.sh'
This approach:
- Starts with empty environment (-i)
- Sources multiple .env files
- Executes the final command without creating a subshell
When implementing your own solution:
- Always sanitize .env file contents
- Consider file permissions (0600 for sensitive files)
- Validate variable names match expected patterns
For production use, prefer established tools that have undergone security audits.
While Foreman provides excellent functionality for managing environment variables through .env files, many developers find it overkill when they simply need to:
- Load environment variables from a file
- Execute a single command with those variables
The Unix philosophy offers several lightweight alternatives:
1. Using env and xargs
A simple one-liner that works on most Unix-like systems:
env $(cat vars.env | xargs) myprogram
2. Shell Script Solution
Create a reusable script called envrun
:
#!/bin/bash
set -a
source $1
shift
exec "$@"
Usage:
./envrun vars.env myprogram
3. envconsul (HashiCorp)
For more complex scenarios:
envconsul -prefix myapp/env -upcase myprogram
For JavaScript developers:
1. dotenv-cli
npm install -g dotenv-cli
dotenv -e vars.env myprogram
2. env-cmd
npx env-cmd -f vars.env myprogram
python -c "import os; [os.environ.update(dict(line.strip().split('='))) for line in open('vars.env')]; os.system('myprogram')"
Tool | Memory Usage | Startup Time |
---|---|---|
Foreman | ~50MB | ~300ms |
env + xargs | <1MB | <10ms |
dotenv-cli | ~15MB | ~100ms |
Always validate your .env files:
grep -qE '^[A-Z0-9_]+=' vars.env || { echo "Invalid .env format"; exit 1; }
For loading multiple .env files:
env $(cat .env.prod .env.local | xargs) myprogram