When working with bash heredoc (< The most reliable solution is quoting the delimiter itself. This disables all special interpretation within the heredoc: While quoting the delimiter is preferred, you can also escape individual dollar signs: Here's how to properly generate an nginx config with literal variables: For mixed content (some variables expanded, others literal), consider these patterns: The key insight is that heredoc behavior changes fundamentally based on whether the delimiter is quoted. For configuration file generation where exact string preservation is crucial, always quote your heredoc delimiters. When working with bash heredocs, you might encounter situations where you need to prevent variable expansion. The shell automatically expands variables within heredoc blocks, which can cause issues when you want to preserve literal dollar signs. The most straightforward solution is to quote the heredoc delimiter: If you only need to escape specific variables: An alternative syntax that works in most shells: For complex cases where you need some variables expanded and others not: When using heredocs within functions, the same rules apply: There's no performance difference between the quoted and unquoted versions - the parsing happens at script interpretation time, not during execution.# Problematic example with unwanted expansion
cat > config.txt <
cat > nginx_config <<'EOF'
server {
listen 80;
server_name $host; # Now preserved literally
root /var/www/$path;
}
EOF
# Method 1: Backslash escape each $
cat > script.sh <
# Correct approach for OP's original problem
cat > /etc/nginx/sites-available/default_php <<'NGINX_CONF'
server {
listen 80 default;
server_name _;
root /var/www/$host; # Now preserved exactly
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php${PHP_VERSION}-fpm.sock;
}
}
NGINX_CONF
# Hybrid approach using different quoting
ACTUAL_VAR="value"
cat > output <
cat > example.sh <
Method 1: Quoting the Heredoc Delimiter
cat > /etc/nginx/sites-available/default_php <<'END'
server {
listen 80 default;
server_name _;
root /var/www/$host; # $host will remain literal
}
END
Method 2: Escaping Individual Dollar Signs
cat > config.txt <
Method 3: Using a Backslash Before EOF
cat << \EOF > output.txt
This $variable won't expand
Neither will this ${another_one}
EOF
Selective Expansion with Mixed Quotes
name="Server1"
cat << "EOF" > config.cfg
Hostname: $name # Won't expand
IP: "$(hostname -I)" # Won't execute
EOF
cat << EOF > config.cfg
Hostname: $name # Will expand
IP: "$(hostname -I)" # Will execute
EOF
Here Documents in Functions
generate_config() {
local port=8080
cat << 'EOT' > nginx.conf
server {
listen ${port}; # Won't expand
# ...
}
EOT
}
How to Disable Variable Interpretation in Bash Heredoc for Literal String Output
1 views