如何在 EOF 标签内扩展变量

How to expand variable inside EOF tag

我下面有一个 bash 脚本:

#!/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

我想将 built_at 变量传递给 EOF 标签内的 golang 变量。但我想保持 'EOF' 不变。我试图在没有 ' 的情况下更改它,但这将是我的 dockerfile 进程的错误。

你不能。您要么允许扩展,要么不允许扩展,并且您不能在 single here 文档中更改它。但是,您可以将此处的文档拆分为多个文档以生成最终输出。例如,

{
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

不过,更好的主意是使用模板工具(m4jinja2 等)。