我正在尝试交叉编译一个Go程序,该程序将执行一个bash脚本。是否可以将bash脚本嵌入到二进制文件中?
我参考了以下内容: Golang serve static files from memory 不确定是否适用于执行bash脚本。我有什么遗漏吗?请提供一些澄清或指针,谢谢!
我参考了以下内容: Golang serve static files from memory 不确定是否适用于执行bash脚本。我有什么遗漏吗?请提供一些澄清或指针,谢谢!
由于 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))
}
在Go中,您实际上可以直接与系统shell进行交互。根据您的bash脚本中包含的内容,您可能可以完全将所有内容转换为Go。例如,处理文件、提取存档、输出文本、请求用户输入、下载文件等等都可以在Go中本地完成。对于您绝对需要使用shell的任何内容,您始终可以使用golang.org/pkg/os/exec。
我编写了一个代码片段,演示了一个非常简单的基于Go的命令shell。基本上,它在用户和shell之间传输输入、输出和错误。它可以交互式地使用,也可以直接运行大多数shell命令。我在这里提到它主要是为了展示Go的操作系统功能。看看它:github.com/lee8oi/goshell.go
你尝试过将流数据(根据go-bindata提供的函数,它返回[]byte)写入临时文件吗?
参见:http://golang.org/pkg/io/ioutil/#TempFile
然后你可以使用syscall执行它。
http://golang.org/pkg/syscall/#Exec
第一个参数需要是一个 shell。
os/exec
包时,请勿使用syscall.Exec
。在没有必要时请勿使用临时文件。 - Dave C