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

从Python程序调用脚本切换pyenv虚拟环境时遇激活失败问题

问题描述

我有一个名为foo的bash脚本,内容如下:

#!/bin/bash

pyenv activate my_env
python main.py

通过. foo或source foo调用该脚本时,能正常切换pyenv虚拟环境并运行main.py。

现在我想从Python程序中调用这个脚本,编写了如下代码:

import os
import subprocess


def main() -> None:
    script_path = 'scripts/foo'
    shell_source(script_path)


def shell_source(script):
    pipe = subprocess.Popen(
        ". %s && env -0" % script,
        stdout=subprocess.PIPE,
        shell=True
        )
    output = pipe.communicate()[0].decode('utf-8')
    output = output[:-1]

    env = {}
    for line in output.split('\x00'):
        line = line.split('=', 1)
        env[line[0]] = line[1]

        os.environ.update(env)


if __name__ == '__main__':
    main()

但运行该Python程序时出现错误:

Failed to activate virtualenv.
Perhaps pyenv-virtualenv has not been loaded into your shell properly.
Please restart current shell and try again.

请问该如何解决这个问题?

解决方案

出现这个错误的核心原因是:subprocess.Popen默认启动的是非交互式shell,不会加载~/.bashrc或~/.profile这类配置文件,而pyenv通常是在这些文件里完成初始化的,导致shell找不到pyenv的命令和虚拟环境激活逻辑。

可以通过以下几种方式解决:

方法1:显式加载pyenv初始化脚本

修改subprocess.Popen的命令,先加载pyenv的配置文件,再执行目标脚本。比如pyenv初始化在~/.bashrc里的话,代码改成:

pipe = subprocess.Popen(
    "source ~/.bashrc && . %s && env -0" % script,
    stdout=subprocess.PIPE,
    shell=True,
    executable="/bin/bash"  # 指定用bash shell,避免默认sh的兼容性问题
)

如果你的pyenv是在~/.profile或~/.bash_profile里配置的,替换成对应的文件路径即可。

方法2:直接调用虚拟环境的Python解释器

既然最终目的是运行main.py,可以跳过pyenv activate步骤,直接调用虚拟环境里的Python路径执行脚本。

先找到my_env虚拟环境的Python路径,通常是~/.pyenv/versions/my_env/bin/python,然后修改Python代码:

def main() -> None:
    python_path = os.path.expanduser("~/.pyenv/versions/my_env/bin/python")
    script_path = "main.py"  # 填写main.py的正确路径
    subprocess.run([python_path, script_path], check=True)

这种方式更直接,避免了shell环境变量传递的复杂问题。

方法3:启动交互式shell

给shell传递-i参数,强制启动交互式bash,它会自动加载~/.bashrc配置:

pipe = subprocess.Popen(
    ". %s && env -0" % script,
    stdout=subprocess.PIPE,
    shell=True,
    executable="/bin/bash -i"
)

不过这种方式可能会引入一些不必要的环境变量,不如前两种方法干净。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 20:20:09