在项目文件夹中运行Python脚本的Golang实现方法
在项目文件夹中运行Python脚本的Golang实现方法 我正在尝试在我的Go项目文件夹中运行一个Python脚本,但不知道该如何运行它。
目前已有的代码:
func runProgram(target string) {
output, err := exec.Command(target).Output()
if err != nil {
panic(err.Error())
}
fmt.Println(string(output))
}
我执行该函数的方式:
func auditTask() {
runProgram("linuxScanner")
}
我一直收到以下错误:
panic: exec: “linuxScanner”: executable file not found in $PATH
我还需要能够将Python脚本与Go代码打包在同一个可执行文件中
更多关于在项目文件夹中运行Python脚本的Golang实现方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html
你可以在这里放置任何你喜欢的字符串。
更多关于在项目文件夹中运行Python脚本的Golang实现方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
非常感谢!
还有一个问题,我该如何运行整个Python脚本,而不是仅仅执行 print("hello")?
抱歉,这可能听起来像个新手问题,但我该如何处理一个大约有100行长的字符串呢?
谢谢!但不幸的是,我遇到了这个错误:
fork/exec python: no such file or directory
NobbZ:
将内容写入 Python 的标准输入来运行它
我该如何实现这个操作?
他甚至应该能够将其写入 Python 的标准输入来运行。这样就不需要创建可能涉及权限问题的临时文件(虽然通常不会出现这种情况)。
NobbZ:
出于某些原因,go 有时会打印这些信息。
当你使用 go run 命令时就会出现这种情况。
如果可执行文件不在 PATH 环境变量中,你需要指定可执行文件的路径,可以是绝对路径或相对路径(当前工作目录使用前导 ./)。
如下所示:
const longString = `#!/usr/bin/env python
lorem
ipsum
dolor
est
imet
and
many
more
lines
with
actual
code
`
首先,感谢您的帮助!
我还有另一个问题(希望是最后一个)。我一直收到这个错误:
panic: exit status 1
然后在堆栈跟踪之后,我还看到:
exit status 2
正如Norbert所说,您必须将linuxScanner放在$PATH变量指定的目录中,或者使用相对路径./linuxScanner(点号表示当前目录),或者使用绝对路径如/home/xxx/my-folder/another-folder/linuxScanner。
如果您想将脚本嵌入到Go程序中,可以按照以下方式实现:
package main
# 反引号用于多行原始字符串
var pythonProgram = `
#!/usr/bin/python
a = "World"
print "Hello " + a
`
然后使用https://golang.org/pkg/io/ioutil/#TempFile将程序写入临时文件,再执行该文件。
这是凭记忆写的,而且我不确定需要如何调用 python 才能从标准输入获取内容,因此您可能需要稍作调整:
package main
import (
"bytes"
"fmt"
"os/exec"
"strings"
)
func main() {
cmd := new(exec.Cmd)
r := strings.NewReader(`print("hello")`)
var o bytes.Buffer
cmd.Path = "python"
cmd.Stdin = r
cmd.Stdout = &o
if err := cmd.Run(); err != nil {
panic(err)
}
fmt.Println("%v", o.String())
}
我猜你是直接从我的示例中复制了 if err := cmd.Run(); err != nil { panic(err) } 这段代码?
所以你的 Python 脚本执行了类似 exit(1) 的操作,这会被理解为执行错误(任何非 0 的返回值都被视为错误),因此会给你一个无用的错误信息,提示执行因 exit status x 而失败。解析这条信息是可靠获取退出代码的唯一方法。
第二个 exit status 2 是你的 Go 程序的退出状态。出于某些原因,Go 有时会打印这个信息。
if err := cmd.Run(); err != nil { panic(err) }
抱歉……我查看了我之前做过类似功能的旧项目,发现我记错了如何创建 exec.Cmd 结构体。
这里有一个修复初始化问题的小补丁,同时也修正了 fmt.Println 的调用 😉
--- x 2018-10-06 08:28:45.734796606 +0200
+++ main.go 2018-10-06 08:27:34.618183208 +0200
@@ -10,3 +10,3 @@
func main() {
- cmd := new(exec.Cmd)
+ cmd := exec.Command("python")
r := strings.NewReader(`print("hello")`)
@@ -14,3 +14,2 @@
- cmd.Path = "python"
cmd.Stdin = r
@@ -22,3 +21,3 @@
- fmt.Println("%v", o.String())
+ fmt.Println(o.String())
}
要解决在Go项目中运行Python脚本的问题,需要明确几个关键点:Python脚本不是可执行二进制文件,必须通过Python解释器运行;同时需要处理脚本路径和打包问题。以下是完整的解决方案:
首先修改runProgram函数,明确指定使用Python解释器并传递脚本路径:
func runPythonScript(scriptPath string) {
// 使用python3执行指定路径的脚本
cmd := exec.Command("python3", scriptPath)
output, err := cmd.Output()
if err != nil {
panic(fmt.Sprintf("执行Python脚本失败: %v", err))
}
fmt.Println(string(output))
}
然后在项目中调用:
func auditTask() {
// 假设Python脚本位于项目根目录,名为linuxScanner.py
runPythonScript("./linuxScanner.py")
}
对于打包到单个可执行文件的需求,需要使用Go的embed功能。首先创建嵌入Python脚本的代码:
import (
_ "embed"
"os"
"os/exec"
"path/filepath"
)
//go:embed linuxScanner.py
var pythonScriptContent string
func runEmbeddedPythonScript() {
// 创建临时文件
tmpfile, err := os.CreateTemp("", "script-*.py")
if err != nil {
panic(fmt.Sprintf("创建临时文件失败: %v", err))
}
defer os.Remove(tmpfile.Name()) // 清理临时文件
// 写入嵌入的Python脚本内容
if _, err := tmpfile.WriteString(pythonScriptContent); err != nil {
panic(fmt.Sprintf("写入临时文件失败: %v", err))
}
if err := tmpfile.Close(); err != nil {
panic(fmt.Sprintf("关闭临时文件失败: %v", err))
}
// 执行Python脚本
cmd := exec.Command("python3", tmpfile.Name())
output, err := cmd.Output()
if err != nil {
panic(fmt.Sprintf("执行Python脚本失败: %v", err))
}
fmt.Println(string(output))
}
使用嵌入版本:
func auditTask() {
runEmbeddedPythonScript()
}
项目结构示例:
project/
├── main.go
├── linuxScanner.py (将被嵌入)
└── go.mod
在main.go同目录下创建linuxScanner.py文件,内容示例:
#!/usr/bin/env python3
print("Python脚本执行成功!")
确保系统已安装Python3,编译Go程序时会自动将Python脚本嵌入到可执行文件中。这种方法既解决了路径问题,也实现了单文件分发的需求。

