使用Go:将Bash脚本嵌入二进制文件中

8
我正在尝试交叉编译一个Go程序,该程序将执行一个bash脚本。是否可以将bash脚本嵌入到二进制文件中?
我参考了以下内容: Golang serve static files from memory 不确定是否适用于执行bash脚本。我有什么遗漏吗?请提供一些澄清或指针,谢谢!
3个回答

7

由于 bash 可以从 stdin 执行脚本,因此您只需通过 command.Stdin 将脚本发送到 bash 命令即可。

以下是一个没有使用 go embed 的示例:

package main

import (
    "bytes"
    "fmt"
    "os/exec"
    "strings"
)

var script = `
echo $PWD
pwd
echo "-----------------------------------"
# print process
ps aux | grep code
`

func main() {
    c := exec.Command("bash")
    c.Stdin = strings.NewReader(script)

    b, e := c.Output()
    if e != nil {
        fmt.Println(e)
    }
    fmt.Println(string(b))
}

使用 Go 1.16 的 embed (https://golang.org/pkg/embed/):

package main

import (
    "bytes"
    _ "embed"
    "fmt"
    "os/exec"
    "strings"
)

//go:embed script.sh
var script string

func main() {
    c := exec.Command("bash")
    c.Stdin = strings.NewReader(script)

    b, e := c.Output()
    if e != nil {
        fmt.Println(e)
    }
    fmt.Println(string(b))
}

奖金

使用 -s - 将参数传递给你的脚本。

下面的例子将会把 -la /etc 传递给脚本。

package main

import (
    "fmt"
    "os/exec"
    "strings"
)

func main() {
    // pass parameters to your script as a safe way.
    c := exec.Command("sh", "-s", "-", "-la", "/etc")

    // use $1, $2, ... $@ as usual
    c.Stdin = strings.NewReader(`
    echo $@
    ls $1 "$2"
    `)

    b, e := c.Output()
    if e != nil {
        fmt.Println(e)
    }
    fmt.Println(string(b))
}

游乐场:https://go.dev/play/p/T1lMSrXcOIL


0

在Go中,您实际上可以直接与系统shell进行交互。根据您的bash脚本中包含的内容,您可能可以完全将所有内容转换为Go。例如,处理文件、提取存档、输出文本、请求用户输入、下载文件等等都可以在Go中本地完成。对于您绝对需要使用shell的任何内容,您始终可以使用golang.org/pkg/os/exec

我编写了一个代码片段,演示了一个非常简单的基于Go的命令shell。基本上,它在用户和shell之间传输输入、输出和错误。它可以交互式地使用,也可以直接运行大多数shell命令。我在这里提到它主要是为了展示Go的操作系统功能。看看它:github.com/lee8oi/goshell.go


-1

当存在 os/exec 包时,请勿使用 syscall.Exec。在没有必要时请勿使用临时文件。 - Dave C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接