如何在Python脚本中运行需激活conda虚拟环境的Bash脚本
问题根因
你遇到的报错是两个原因导致的:
os.system和subprocess.run每次调用都会开启独立的子shell进程,前一个命令运行完成后子shell就销毁了,后续运行的新子shell不会继承前一个shell的环境,所以单独运行conda activate bne完全没有效果。- 非交互模式的shell默认不会加载conda的初始化配置,所以直接在子shell中运行
conda activate会找不到命令。
可行解决方案
优先推荐第一种方案,最适配集群环境:
方案1:直接调用目标虚拟环境的Python解释器(最推荐)
不需要显式激活虚拟环境,直接使用虚拟环境中Python解释器的绝对路径运行脚本,就能自动使用该环境的所有依赖,实现环境隔离。
操作步骤
- 在集群终端中执行以下命令,获取bne环境的Python解释器绝对路径:
conda activate bne which python
得到的输出类似/home/你的用户名/miniconda3/envs/bne/bin/python,记录该路径。
2. 修改你的Python函数如下:
import os import subprocess def do_tensorflow_routine(path_name_file): work_dir = os.path.join("../", "bne_resources/") # 替换为你自己查询到的bne环境Python路径 bne_python_path = "/home/你的用户名/miniconda3/envs/bne/bin/python" bne_command = [ bne_python_path, "bne.py", "--model", "models/BNE_SGsc", "--fe", "./embeddings/BioEmb/Emb_SGsc.txt", "--fi", "names.txt", "--fo", "names_bne_SGsc.txt" ] subprocess.run( bne_command, cwd=work_dir, # 直接指定子进程工作目录,不需要修改父进程路径 check=True, # 子进程运行失败则直接抛出异常,方便排查 env={**os.environ, "CUDA_VISIBLE_DEVICES": "1"} # 传入环境变量 )
方案2:单shell内执行完整激活+运行命令
如果你需要显式执行conda activate操作,可以将所有相关命令放在同一个子shell中运行,同时提前加载conda的初始化配置:
import os import subprocess def do_tensorflow_routine(path_name_file): work_dir = os.path.join("../", "bne_resources/") bne_command = """ # 加载conda初始化脚本,路径替换为你自己的conda安装路径下的对应文件 source ~/miniconda3/etc/profile.d/conda.sh conda activate bne CUDA_VISIBLE_DEVICES=1 python bne.py --model models/BNE_SGsc --fe ./embeddings/BioEmb/Emb_SGsc.txt --fi names.txt --fo names_bne_SGsc.txt """ subprocess.run( bne_command, shell=True, cwd=work_dir, executable="/bin/bash", # 指定用bash运行,避免sh不支持source命令 check=True )
注意事项
- 集群环境优先使用方案1,不需要依赖shell配置,不会因为不同节点的环境变量差异出现运行失败的问题。
- 所有操作都不需要修改父Python脚本的运行环境,两个虚拟环境完全隔离,不会出现依赖冲突。
内容的提问来源于stack exchange,提问作者Megh
相关产品推荐
相关产品推荐

