If you’ve ever worked with Linux configuration files or deployment scripts, you may have come across a need to replace variables dynamically. One tool that’s often overlooked but incredibly powerful is envsubst—a command-line utility designed specifically for substituting environment variables in shell-style templates. Whether you’re managing Docker deployments, initializing configuration files, or automating infrastructure, envsubst offers a clean, secure, and elegant way to handle variable interpolation.
TL;DR
envsubst is a simple command-line tool that replaces environment variables in strings or files. It is commonly used in DevOps and shell scripting to template configuration files. You run it by piping a template file through envsubst, and the output contains the replaced variables. It’s secure, scriptable, and avoids using more complex tools like sed or awk for basic substitution.
What is Envsubst?
The name envsubst stands for “environment substitute.” It is a utility that ships with the gettext package in most Unix-based systems. Envsubst reads input—either from standard input or from a file—and replaces any shell-style variable references such as $VAR or ${VAR} with their corresponding environment variable values.
This makes envsubst highly valuable in situations where configuration files need to be templated dynamically, especially in containerized environments where variables might be set at runtime.
Prerequisites
Before you get started, make sure the following are in place:
- You are running a Linux or Unix-based system.
- Ensure that the
gettextpackage is installed. - You have at least basic knowledge of shell scripting and environment variables.
Installing Envsubst
In most cases, envsubst is already available on your system. However, if it’s missing, you can easily install it by installing the gettext package:
- Debian/Ubuntu:
sudo apt install gettext - Red Hat/CentOS:
sudo yum install gettext - macOS (with Homebrew):
brew install gettext
Basic Usage
Let’s take a look at the simplest way to use envsubst. Suppose you have the following template file called greeting.txt:
Hello, $USER_NAME! Welcome to $PLATFORM_NAME.
Assuming the environment variables are defined as:
export USER_NAME="Alice" export PLATFORM_NAME="Linux Academy"
You can run:
envsubst < greeting.txt
And the output will be:
Hello, Alice! Welcome to Linux Academy.
Selective Variable Substitution
envsubst also allows you to specify which variables you want to substitute. This can be especially useful when templating files where other variables should remain untouched.
envsubst '$USER_NAME' < greeting.txt
In this case, only $USER_NAME will be substituted, and $PLATFORM_NAME will remain as-is.
Redirecting Output to a File
It’s often useful to write the substituted results to a new file instead of printing them to the screen. This is easily done using output redirection:
envsubst < input_template.conf > final_output.conf
This is a common practice when preparing configuration files for applications like Nginx, PostgreSQL, or Docker containers.
Using Envsubst in Shell Scripts
Envsubst blends seamlessly with shell scripting. Here’s a quick example of how you might embed it inside a Bash script:
#!/bin/bash export DB_USER="admin" export DB_PASS="s3cret" envsubst < db_config.template > db_config.conf
The db_config.template file might look like this:
user = $DB_USER password = $DB_PASS
After running the script, db_config.conf will have the variables replaced appropriately. This approach is frequently used in CI/CD pipelines where templates are stored in version control but credentials and sensitive data are injected by the environment at runtime.
Handling Default Values
Sometimes not all variables may be defined at script start time. In such cases, use shell variable expansion syntax to provide default values:
Hello, ${USER_NAME:-Guest}!
If $USER_NAME is not defined, “Guest” will be used.
Security Considerations
One of the biggest advantages of envsubst over alternatives like sed or awk is security and predictability. Since it only substitutes environment variables—not arbitrary patterns—it reduces the chance of accidentally replacing unintended content.
However, be cautious when sourcing environment variables from untrusted sources, especially if they will be substituted into configuration files. Avoid exposing secrets in logs or command history files.
Advanced Example: Docker Integration
Here’s a more advanced use case: templating a Docker configuration file.
# docker.env APP_NAME=MyApp APP_PORT=8080
# docker-compose.yml.template
version: "3"
services:
app:
image: myapp:latest
environment:
- APP_NAME=$APP_NAME
- PORT=$APP_PORT
ports:
- "$APP_PORT:$APP_PORT"
You can prepare your final Docker Compose file with:
set -a . ./docker.env set +a envsubst < docker-compose.yml.template > docker-compose.yml
The set -a and set +a commands ensure all variables from the .env file are exported into the environment, so envsubst can access them.
Common Pitfalls to Avoid
Here are some of the most frequent mistakes users encounter when using envsubst:
- Using single quotes instead of double quotes: Single-quoted strings won’t allow variable interpolation.
- Not exporting variables: Only exported environment variables are visible to envsubst.
- Variable not declared: Ensure all variables used in templates are defined in the shell environment.
- Using syntax incompatible with shell-style variables: Envsubst supports only
$VARand${VAR}, not double curly braces like{{VAR}}.
Alternatives to Envsubst
While envsubst is suitable for simple use cases, there are tools that offer more complex templating features:
- Mustache or Jinja2: For more advanced logic, including loops and conditionals.
- yq or jq: For structured data such as YAML or JSON manipulation.
- Consul Template: For service discovery and dynamic configuration.
However, these tools are significantly heavier and may not be necessary if your sole requirement is environment variable substitution, which envsubst handles well and securely.
Conclusion
envsubst stands out as a minimal, efficient tool for injecting environment variables into text files or templates in Unix environments. It is particularly useful in DevOps workflows, shell scripting, and container orchestration tasks. While it lacks the complexity of full-blown template engines, its simplicity is exactly what makes it reliable and easy to maintain.
By understanding its features, limitations, and best practices, you can leverage envsubst to streamline configuration processes and maintain clean, version-controlled templates that are dynamically populated at runtime.