Output Formats
title: Output Formats audience: Developer difficulty: Beginner estimated_read_time: 4 min prerequisites:
- CLI installed
- Understanding of shell environments related_pages:
- ./envcat-get.md
- ../concepts/bundles.md
envcat supports three output formats for environment variables: shell exports (sh), Fish shell (fish), and dotenv files (.env).
Format Comparison
| Format | Use Case | Shell | Quoting | Best For |
|---|---|---|---|---|
sh | Bash/Zsh exports | bash, zsh, sh | Single quotes | eval injection |
fish | Fish shell | fish | No quotes | Fish source |
.env | Dotenv files | Any | Minimal | Docker, direnv |
Shell Format (sh)
Default format for bash, zsh, and POSIX shells.
Syntax
export KEY='value'
Example
Command:
envcat get --bundle dev/api --format sh
Output:
export DATABASE_URL='postgres://user:pass@localhost:5432/db'
export API_KEY='sk_live_abc123xyz'
export PORT='3000'
export DEBUG='true'
Usage
Eval (recommended):
eval "$(envcat get --bundle dev/api --format sh)"
echo $DATABASE_URL
# postgres://user:pass@localhost:5432/db
To file:
envcat get --bundle dev/api --format sh > exports.sh
source exports.sh
Quoting Rules
envcat uses single quotes with proper escaping for shell safety.
Simple values:
export PORT='3000'
export DEBUG='true'
Values with spaces:
export MESSAGE='Hello World'
Values with single quotes:
export QUOTE='He said '"'"'hi'"'"''
# Expands to: He said 'hi'
Values with special characters:
export PASSWORD='p@$$w0rd!#%'
export URL='postgres://user:pa$$@localhost:5432/db?sslmode=disable'
Multiline values:
export MULTILINE='line1
line2
line3'
Why Single Quotes?
Single quotes prevent:
- Variable expansion (
$VAR) - Command substitution (
`cmd`) - Glob expansion (
*.txt) - History expansion (
!!)
Example of protection:
# Unsafe (double quotes)
export DANGER="rm -rf $HOME"
# Safe (single quotes)
export DANGER='rm -rf $HOME'
# $HOME NOT expanded
Edge Cases
Empty values:
export EMPTY=''
Values with newlines:
export CERT='-----BEGIN CERTIFICATE-----
MIIBkTCB+wIJAKHH...
-----END CERTIFICATE-----'
Unicode:
export GREETING='Hello 世界 🌍'
Fish Format (fish)
Format for Fish shell.
Syntax
set -x KEY value
Example
Command:
envcat get --bundle dev/api --format fish
Output:
set -x DATABASE_URL postgres://user:pass@localhost:5432/db
set -x API_KEY sk_live_abc123xyz
set -x PORT 3000
set -x DEBUG true
Usage
Source (recommended):
envcat get --bundle dev/api --format fish | source
echo $DATABASE_URL
# postgres://user:pass@localhost:5432/db
To file:
envcat get --bundle dev/api --format fish > exports.fish
source exports.fish
Differences from sh
No quotes:
Fish handles quoting internally, so envcat doesn't add quotes.
# envcat output
set -x MESSAGE Hello World
# Fish interprets as single value
echo $MESSAGE
# Hello World (not "Hello" separately)
Spaces handled:
set -x MULTILINE line1
line2
line3
# Fish preserves newlines
Why set -x?
set- Set variable-x- Export to environment (likeexportin bash)
Without -x:
set PORT 3000
# Only available in Fish, not exported to child processes
With -x:
set -x PORT 3000
# Exported to child processes (like node, python, etc.)
Dotenv Format (.env)
Standard dotenv format for Docker, direnv, and dotenv libraries.
Syntax
KEY=value
Example
Command:
envcat get --bundle dev/api --format .env
Output:
DATABASE_URL=postgres://user:pass@localhost:5432/db
API_KEY=sk_live_abc123xyz
PORT=3000
DEBUG=true
Usage
Write to file:
envcat get --bundle dev/api --file .env
Load into shell:
set -a && source .env && set +a
Docker Compose:
# docker-compose.yml
services:
api:
env_file:
- .env
Node.js (dotenv library):
require('dotenv').config();
console.log(process.env.DATABASE_URL);
Python (python-dotenv):
from dotenv import load_dotenv
load_dotenv()
import os
print(os.getenv('DATABASE_URL'))
Quoting Rules
Minimal quoting:
dotenv format uses quotes only when necessary.
No quotes (default):
PORT=3000
DEBUG=true
DATABASE_URL=postgres://localhost:5432/db
Quotes for spaces:
MESSAGE="Hello World"
Quotes for special chars:
PASSWORD="p@$$w0rd!#"
URL="postgres://user:pa$$@localhost?sslmode=disable"
No quotes for single-word values:
NODE_ENV=production
LOG_LEVEL=info
Comments
envcat does NOT add comments to .env files. Comments are manual.
Example with manual comments:
# Database
DATABASE_URL=postgres://localhost:5432/db
DATABASE_POOL_SIZE=10
# API Keys
API_KEY=sk_live_abc123xyz
STRIPE_KEY=pk_live_xyz789abc
Variable Expansion
Not supported in envcat output:
envcat outputs literal values, not variable references.
# envcat does NOT output this:
BASE_URL=https://api.example.com
API_URL=${BASE_URL}/v1
# envcat outputs literal values:
BASE_URL=https://api.example.com
API_URL=https://api.example.com/v1
If you need variable expansion, use direnv or shell scripts.
Multiline Values
Supported with quotes:
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA...
-----END RSA PRIVATE KEY-----"
Best practice: Use base64 encoding for multiline secrets.
PRIVATE_KEY_BASE64=LS0tLS1CRUdJTi...
Then decode in application:
echo $PRIVATE_KEY_BASE64 | base64 -d
Format Selection
When to Use sh
✅ Use sh when:
- Working in bash/zsh/sh
- Using
evalpattern - Need shell-safe quoting
- Want to inject directly into current shell
Example:
eval "$(envcat get --bundle dev/api --format sh)"
npm start
When to Use fish
✅ Use fish when:
- Working in Fish shell
- Using
sourcepattern - Fish-specific configuration
Example:
envcat get --bundle dev/api --format fish | source
npm start
When to Use .env
✅ Use .env when:
- Using Docker/Docker Compose
- Using direnv
- Using dotenv libraries (Node.js, Python, Ruby)
- Need persistent file
- Sharing across tools
Example:
envcat get --bundle dev/api --file .env
docker-compose up
Automatic Format Selection
With --write or --file
Always uses .env format:
envcat get --bundle dev/api --write .env --format sh
# Ignored: --format sh
# Used: .env format
Reason: File output is typically for Docker/direnv, which expect .env format.
Default Format
When no flags specified:
envcat get --bundle dev/api
# Uses: sh format (default)
Practical Examples
Bash Development
# Development
eval "$(envcat get --bundle dev/api --format sh)"
npm run dev
# Production
eval "$(envcat get --bundle prod/api --format sh)"
npm start
Fish Development
# Development
envcat get --bundle dev/api --format fish | source
npm run dev
# Production
envcat get --bundle prod/api --format fish | source
npm start
Docker Workflow
# Generate .env
envcat get --bundle dev/api --file .env
# Start services
docker-compose up
# Cleanup
rm .env
Direnv Integration
.envrc:
#!/bin/bash
envcat get --bundle dev/api --file .env.tmp
dotenv .env.tmp
rm .env.tmp
Or simpler:
#!/bin/bash
eval "$(envcat get --bundle dev/api)"
CI/CD
GitHub Actions:
- name: Load secrets
run: |
envcat get --bundle ci/github --file .env
cat .env >> $GITHUB_ENV
GitLab CI:
before_script:
- envcat get --bundle ci/gitlab --file .env
- export $(cat .env | xargs)
Format Debugging
Compare Formats Side-by-Side
Shell format:
envcat get --bundle dev/api --format sh
Fish format:
envcat get --bundle dev/api --format fish
Dotenv format:
envcat get --bundle dev/api --format .env
Verify Quoting
Test special characters:
# Create test bundle with special chars
# Then compare formats:
envcat get --bundle test/special --format sh
# export QUOTE='He said '"'"'hi'"'"''
envcat get --bundle test/special --format fish
# set -x QUOTE He said 'hi'
envcat get --bundle test/special --format .env
# QUOTE="He said 'hi'"
Troubleshooting
Variables Not Loading
Issue: eval doesn't load variables
Solution: Check format matches shell
# Wrong: Using fish format in bash
eval "$(envcat get --bundle dev/api --format fish)"
# Error: set: command not found
# Correct: Use sh format in bash
eval "$(envcat get --bundle dev/api --format sh)"
Docker Can't Parse .env
Issue: Docker Compose fails to load .env
Solution: Use .env format, not sh format
# Wrong:
envcat get --bundle dev/api --format sh > .env
docker-compose up
# Error: export: command not found
# Correct:
envcat get --bundle dev/api --file .env
docker-compose up
Fish Syntax Error
Issue: source fails with syntax error
Solution: Use fish format, not sh format
# Wrong:
envcat get --bundle dev/api --format sh | source
# Error: export: Unknown command
# Correct:
envcat get --bundle dev/api --format fish | source
See Also
- envcat get - Complete flag reference
- Examples - More use cases
- Troubleshooting - Common issues