Skip to main content

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

FormatUse CaseShellQuotingBest For
shBash/Zsh exportsbash, zsh, shSingle quoteseval injection
fishFish shellfishNo quotesFish source
.envDotenv filesAnyMinimalDocker, 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 (like export in 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 eval pattern
  • 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 source pattern
  • 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