'How to expand variable inside EOF tag

I have a bash script below :

#!/bin/sh

set -e

go mod init broken_env

built_at=`date -u "+%d-%m-%y@%H"`
cat > main.go <<'EOF'
package main

import (
        "encoding/json"
        "log"
        "net/http"
)

const (
        builtAt string = ${built_at}
        address string = ":8228"
)

func main() {
        http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
                w.WriteHeader(http.StatusOK)
                w.Header().Set("Content-Type", "application/json")

                json.NewEncoder(w).Encode(map[string]string{
                        "built_at": builtAt,
                })
        })

        log.Println("run at", address)
        http.ListenAndServe(address, nil)
}
EOF

I want to pass the built_at variable into the golang variable which is inside the EOF tag. But I want to keep 'EOF' as it is. I have tried to change it without ' but it will be an error on my dockerfile process.



Solution 1:[1]

You can't. You either allow expansion, or you don't, and you can't change that in a single here document. You can, however, split the here document into multiple documents to produce the final output. For example,

{
cat <<'EOF'
package main

import (
        "encoding/json"
        "log"
        "net/http"
)
EOF

cat <<EOF
const (
        builtAt string = ${built_at}
        address string = ":8228"
)
EOF

cat <<'EOF'

func main() {
        http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
                w.WriteHeader(http.StatusOK)
                w.Header().Set("Content-Type", "application/json")

                json.NewEncoder(w).Encode(map[string]string{
                        "built_at": builtAt,
                })
        })

        log.Println("run at", address)
        http.ListenAndServe(address, nil)
}
EOF
} > main.go

A better idea, though, would be to use a templating tool (m4, jinja2, etc).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 chepner