You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Golang变量传递给Bash脚本?现有代码场景下的实现方案

问题描述

用户现有如下script.sh脚本:

#!/bin/sh
dbt run --select $model_tag --profiles-dir .

该脚本需要接收来自Go服务代码invoke.go的model_tag变量。invoke.go是一个HTTP服务,核心代码如下:

package main

import (
    "fmt"
    "log"
    "net/http"
    "os"
    "os/exec"
)

func handler(w http.ResponseWriter, r *http.Request) {
    log.Print("helloworld: received a request")
    mt := r.Header.Get("Model-Tag")

    cmd := exec.CommandContext(r.Context(), "/bin/sh","script.sh")
    cmd.Stderr = os.Stderr
    out, err := cmd.Output()
    if err != nil {
        w.WriteHeader(500)
    }
    w.Write(out)
}

func main() {
    log.Print("helloworld: starting server...")

    http.HandleFunc("/", handler)

    port := os.Getenv("PORT")
    if port == "" {
        port = "8080"
    }

    log.Printf("helloworld: listening on %s", port)
    log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
}

在handler函数中,mt是从请求头获取的变量,用户希望将mt赋值给script.sh中的model_tag后执行脚本,但直接设置出现语法错误,需要正确的实现方法。

解决方案

有两种可靠的方式可以实现变量传递,避免语法错误:

方法一:通过环境变量传递

1. 修改script.sh读取环境变量

将脚本中的$model_tag改为读取环境变量(大写是Shell环境变量惯例,也可保持原变量名,只要两边对应即可):

#!/bin/sh
dbt run --select "$MODEL_TAG" --profiles-dir .

2. 在Go代码中设置环境变量

创建exec.Cmd后,复制当前进程环境并添加目标变量:

func handler(w http.ResponseWriter, r *http.Request) {
    log.Print("helloworld: received a request")
    mt := r.Header.Get("Model-Tag")

    // 复制原有环境变量,避免覆盖系统默认配置
    env := os.Environ()
    env = append(env, fmt.Sprintf("MODEL_TAG=%s", mt))

    cmd := exec.CommandContext(r.Context(), "/bin/sh","script.sh")
    cmd.Env = env
    cmd.Stderr = os.Stderr
    out, err := cmd.Output()
    if err != nil {
        w.WriteHeader(500)
        fmt.Fprintf(w, "执行脚本出错: %v", err)
        return
    }
    w.Write(out)
}

这种方式安全性更高,能避免命令注入风险,且无需修改脚本调用方式。

方法二:通过命令行参数传递

1. 修改script.sh接收位置参数

将脚本改为接收第一个命令行参数:

#!/bin/sh
# $1表示传入的第一个命令行参数
dbt run --select "$1" --profiles-dir .

2. 在Go代码中传递参数

调用脚本时直接将mt作为参数传入:

func handler(w http.ResponseWriter, r *http.Request) {
    log.Print("helloworld: received a request")
    mt := r.Header.Get("Model-Tag")

    // 将mt作为参数传给script.sh
    cmd := exec.CommandContext(r.Context(), "/bin/sh","script.sh", mt)
    cmd.Stderr = os.Stderr
    out, err := cmd.Output()
    if err != nil {
        w.WriteHeader(500)
        fmt.Fprintf(w, "执行脚本出错: %v", err)
        return
    }
    w.Write(out)
}

这种方式直观简洁,适合简单的参数传递场景。

内容的提问来源于stack exchange,提问作者Tanay Maheshwari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 02:01:31