为了账号安全,请及时绑定邮箱和手机立即绑定

在 Go os/exec 命令中激活 Python venv

在 Go os/exec 命令中激活 Python venv

Go
蓝山帝景 2022-10-17 19:23:23
我正在尝试从 Go os/exec Command&Run方法“激活”(或更确切地说是伪激活)python 虚拟环境,以用于其他命令执行。我知道每个命令执行实际上都是一次隔离运行,因此不会保留环境变量等,因此我一直在尝试手动重新创建激活期间发生的环境更改。根据文档,这应该是可能的:您不需要特别激活环境;激活只是将虚拟环境的二进制目录添加到您的路径中,以便“python”调用虚拟环境的 Python 解释器,您可以运行已安装的脚本而无需使用它们的完整路径。但是,安装在虚拟环境中的所有脚本都应该可以在不激活它的情况下运行,并自动使用虚拟环境的 Python 运行。但是,当我在 Go 中尝试此操作时,我无法获得在虚拟环境中运行的命令 - 例如pip install requests始终安装到全局 pip 缓存。下面是我正在使用的代码:  func Run(cmd *exec.Cmd) (exitCode int, err error) {    cmdErr := cmd.Run()    if cmdErr != nil {          exitCode, err = getExitCode(cmdErr)     }    return exitCode, err  }  func getExitCode(exitError error) (rc int, err error) {    if exitErrorOnly, ok := exitError.(*exec.ExitError); ok {        waitStatus := exitErrorOnly.Sys().(syscall.WaitStatus)        rc = waitStatus.ExitStatus()    } else {        err = fmt.Errorf("could not get exit code, using default")    }    return rc, err  }  func main() {    // using pre-existing venv for testing    const venv = "C:\\Users\\acalder\\Projects\\go\\runinvenv\\venv"    cmd := exec.Command("pip", "install", "requests")    cmd.Stdout = os.Stdout    cmd.Stderr = os.Stderr    cmd.Env = append(os.Environ(),        // these were the only ones i could see changing on 'activation'        "VIRTUAL_ENV=" + venv,        "PATH=" + venv + "\\Scripts;" + os.Getenv("PATH"),    )    exitCode, err := Run(cmd)    fmt.Println("exitCode:", exitCode)    fmt.Println("err:", err)  }
查看完整描述

1 回答

?
缥缈止盈

TA贡献2041条经验 获得超4个赞

当你运行时:

cmd := exec.Command("pip", "install", "requests")

Go 调用 exec.LookPath以查找pip可执行文件的文件路径。由于您在调用PATH后添加了对环境变量的调整,因此将指向您的系统 python。您可以通过在调用后打印来确认这一点。exec.Commandcmd.Pathcmd.Pathexec.Command

我建议将“pip”替换为 venv 中“pip”可执行文件的位置。(对不起,我不懂windows)像:

cmd := exec.Command("C:\\Users\\acalder\\Projects\\go\\runinvenv\\venv\\bin\\pip", "install", "requests")

或者:

    cmd := exec.Command("pip", "install", "requests")
    cmd.Path = "C:\\Users\\acalder\\Projects\\go\\runinvenv\\venv\\bin\\pip"

由于 exec.LookPath 依赖于os.Getenv,或者我认为这也可以:

os.Setenv("PATH",  venv + "\\Scripts;" + os.Getenv("PATH"))
cmd := exec.Command("pip", "install", "requests")

一旦你开始工作并且“pip”指向正确的位置,我猜你仍然需要更新cmd.Env(就像你已经拥有的那样),以便对“pip”或“python”的任何底层调用也使用正确的可执行文件在你的venv。


查看完整回答
反对 回复 2022-10-17
  • 1 回答
  • 0 关注
  • 143 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号