这篇命令整理,是我这几年在无数台机器、无数个项目里反反复复敲出来的经验汇总。你可能已经在网上看过不少 conda 命令清单,但大多是机械罗列,看完记不住,记了不知道怎么组合用。
先花两分钟把整体脉络捋清楚:我会先讲清楚 conda 解决什么问题、和 pip 到底什么关系;然后从安装初始化开始,一条命令一条命令带你走完从创建环境到删除环境的完整生命周期;再单独讲 channel 配置和加速下载的细节;最后是跨版本 Python、CUDA 隔离、IDE 联动,以及我踩过的那些坑。整个过程里我不会只说"这条命令是干嘛的",还会告诉你它在底层做了什么、什么时候能用它、什么时候换个思路更合适。
如果你刚接触命令行,这篇文章完全可以当作第一份 conda 入门资料;如果你已经用了一段时间但总被报错卡住,直接跳到第 2 节和第 7 节,大概率能找到你想要的答案。
1. Conda到底解决了什么问题:环境隔离不是选项,是必需品
1.1 为什么我会从"系统Python一把梭"转向Conda
我刚接触 Python 的时候,想法很简单:装一个 Python,再用 pip 把需要的包装上,够用就行。直到有一次接手一个项目,项目文档里写着需要numpy==1.19,而我本机早就是numpy>=1.24了。我天真地执行了pip install numpy==1.19,结果另一个正在跑的训练脚本直接崩了——它依赖新版 numpy 的某个 API。
这就是"把系统环境当草稿纸用"的代价。一旦你的项目不止一个,不同的依赖版本、不同的 Python 版本、甚至不同的 CUDA 版本就会互相打架。你不可能每换一个项目就把系统重装一遍,这时候环境隔离工具就是必需品,Cond a 正是做这件事的。
Conda 不仅仅是一个 Python 包管理器,它管理的对象是整个"环境":Python 解释器版本、C/C++ 动态库、CUDA 工具包、以及 Python 包本身。它会把这一切装在一个独立的目录里,项目之间互不干扰,想删就删,想重建就重建。
1.2 Conda和pip、virtualenv到底有什么不同
很多人第一次接触时都会问:已经有 pip 了,为什么还要 conda?
| 对比维度 | Conda | pip + virtualenv/venv |
|---|---|---|
| 环境隔离 | 原生支持,隔离Python解释器和所有包 | venv 可以隔离 Python 包,但解释器本身通常复用系统 |
| 包类型 | 不限于 Python 包,还能装 C/C++ 库、CUDA、可执行程序 | 主要是 Python 包 |
| 依赖解析 | 基于 SAT 求解器,会解析二进制依赖 | 依赖解析较简单,二进制冲突需自己处理 |
| 非 Python 依赖 | 自动处理,比如pyo3、cudatoolkit这类编译产物 | 很多需要自己编译,或依赖系统已有库 |
| Channel 机制 | 支持多 channel,每个 channel 就是一个软件仓库 | 默认只有 PyPI |
简单理解:pip 是"给这个 Python 装包",conda 是"造一个完整的运行环境再往里面放东西"。对于涉及科学计算、深度学习、C++ 扩展的项目,conda 能省掉大量编译和动态库冲突的麻烦。
不过 conda 也不是银弹。某些冷门包在 conda 仓库里没有,或者版本更新慢,这时候还是要回归 pip。合理的姿势是:以 conda 为主,conda 装不到再用 pip 补,这个顺序问题我在第 7.2 节会专门展开。
2. 安装与初始化:conda activate报错的真正解法
2.1 一次装好:Anaconda还是Miniconda
我的建议很直接:如果你只是想把环境管好、按需装包,装 Miniconda 就够了。
Anaconda 是一个全家桶发行版,预装了几百个科学计算包,确实省事,但代价是基础体积巨大、包版本之间容易互相锁定,升级时常常拖家带口。Miniconda 只带 conda 自身和最小依赖,环境干净,剩下的包按需安装。对于需要精确控制依赖的场景,Miniconda 才是正解。
装完之后第一步,确认安装是否成功:
conda --version conda infoconda --version只输出版本号,conda info能看到安装路径、Python 版本、channel 配置等关键信息。我建议每次都先跑一下conda info,重点看base environment的路径是不是你预期的地方。如果你曾经装过 Anaconda 又卸载,很容易在系统里残留另一个 conda,后面所有命令都会变得神出鬼没。
2.2 conda init的机制:别只记得执行,忘了重启Shell
这是新手最常遇到的报错,原话大概是:
CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'. To initialize your shell, run $ conda init注意这句话本身就已经给了解决方案,但很多人执行完conda init之后,直接在同一个终端窗口里再次尝试conda activate,还是报错,于是以为 conda init 没用。
conda init做的事情是往你的 shell 配置文件里写入一段初始化代码,比如用 bash 就写在~/.bashrc,用 zsh 就写在~/.zshrc。它告诉 shell:以后每次打开终端,要把 conda 的可执行目录加入 PATH,并定义conda这个 shell 函数。问题是当前这个已经打开的终端窗口还停留在旧环境里,它不会自动重新加载配置。
所以正确流程是:
conda init bash然后关闭终端窗口,重新打开一个新窗口,或者执行source ~/.bashrc强制刷新。之后再执行conda activate 环境名就正常了。
实操里还会遇到另一种情况:公司发的电脑用的是老版 bash,或者你默认 shell 是 fish、powershell,这时conda init后面要带上你的实际 shell 类型。先执行echo $SHELL确认,再用对应的参数初始化。不然等初始化完发现没生效,排查半天才发现是 shell 对不上。
2.3 安装完第一时间检查的四个状态
我每次在新机器上装完 conda,都会按固定顺序做四件检查,养成了习惯之后能少踩很多坑:
# 1. 确认 conda 本体可用 conda --version # 2. 确认当前用的是哪一个 conda,避免多实例并存 which conda # 3. 查看已有环境列表 conda env list # 4. 查看当前 channel 配置 conda config --show channelswhich conda这步常常被人忽略。如果输出结果显示你用的还是路径/usr/bin/conda,说明 shell 优先找到了某个系统级或残留的 conda,即使版本号对,后续创建环境时也可能写到奇怪的位置去。比较干净的输出应该指向 Miniconda 安装目录下的bin/conda。
conda env list的输出里,带*的是当前激活的环境,base右侧会显示它的完整路径。这个命令在后续排查"我的环境到底建在哪了"时非常有价值。
3. 从零到一跑通命令链:创建环境、装包、卸载、查信息
3.1 创建环境:别再硬等,搞清楚create在干什么
创建环境是我使用频率最高的命令,没有之一:
conda create -n myenv python=3.9-n是--name的缩写,后面跟环境名myenv。python=3.9表示在这个环境里装 Python 3.9。执行这条命令时,conda 会做三件事:
- 解析依赖关系,找出 Python 3.9 在所选 channel 下的所有依赖包;
- 从 channel 下载对应的包;
- 在 conda 的
envs目录下创建目录,把 Python 解释器和依赖包放进去。
很多人会遇到创建环境特别慢的情况,卡在Solving environment那一步,屏幕上就是不出结果。这通常不是机器卡了,而是 conda 在拿 SAT 求解器做依赖解析,当 channel 里包非常多、约束又复杂时,解析时间会很长。第一次创建环境时我干等过十分钟,后来学会了两个优化手段:
- 创建时直接指定版本范围,比如
python=3.9,别写python裸装最新版; - 把 channel 配置好,减少默认 channel 的数量,第 5 节会详细说。
如果不想让 conda 每一步都问你要不要继续,可以加-y参数,默认接受安装计划:
conda create -n myenv python=3.9 -y还有一个冷门但很实用的参数-p,直接指定环境创建到哪个路径下:
conda create -p /data/workspace/myenv python=3.9-n创建的环境会统一放在~/miniconda3/envs/下,-p则是完全自定义路径。对于公司要求把大环境放在数据盘、或者多个用户共用一台机器需要共享目录的场景,-p是刚需。
3.2 安装与管理包:conda install的常用参数
环境创建好之后,第一件事就是激活它:
conda activate myenv这时候终端提示符前面会多出(myenv),说明你已经进入这个环境。之后装包,直接:
conda install numpy conda install pandas matplotlib一次装多个包没问题,conda 会把它们作为一个整体做依赖解析,能有效避免逐个安装时出现的版本冲突。
安装特定版本:
conda install numpy=1.23.4指定 channel 安装:
conda install -c conda-forge pillow-c表示临时把某个 channel 加入本次安装的搜索列表,-c conda-forge就是临时使用 conda-forge 频道。注意这和你往配置文件里长期添加 channel 是两回事,前者只对当前命令生效。
更新包和环境:
conda update numpy conda update --all conda update condaconda update --all会把当前环境里所有包升级到符合依赖约束的最新版本。这个命令我建议慎用,尤其是项目进行到中期时,一次全量升级经常把原本稳定运行的环境弄崩。更好的做法是有针对性地只升级你需要的包。
卸载包:
conda remove numpy conda remove -n myenv scipy第二种写法比先激活环境再 remove 更保险,因为你不必真的进入那个环境,命令层面直接指定环境名就能操作。
3.3 查看环境与包:命令虽简单,输出信息量很大
日常查询类命令看着简单,但输出信息往往很有价值:
# 查看所有环境 conda env list # 查看当前环境里安装的包 conda list # 查看某个包是否已安装及其版本 conda list numpy # 搜索某个包有哪些可用版本 conda search numpyconda list输出里每一行是"包名 + 版本号 + 来源版本号 + channel"。来源版本号主要是 build 字符串,它能帮你判断这个包是从哪个 channel 装的、是否基于 MKL 编译等,在排查科学计算包性能异常时很有用。
conda search numpy可以直接看到所有 channel 下存在的 numpy 版本号,还能看到每个版本的 build 标识。想装一个冷门版本时,先 search 一下确认它真实存在,可以避免一堆红字报错。
另外,pip list也可以查看当前环境的 Python 包,但它只会列出纯 Python 包,看不到 conda 管理的非 Python 依赖。排查问题时建议 conda list 和 pip list 配合看。
4. 环境管理进阶:clone、导出、删除、迁移一气呵成
4.1 复制环境与导出配置文件
当我对当前环境做了大量调试,终于调出一个能跑通的组合时,第一反应就是赶紧留个快照。最直接的方式是 clone 一份:
conda create -n myenv_backup --clone myenv--clone会把myenv里的所有包、版本、channel 信息原样复制到新环境。这个操作依赖 conda 在本地缓存和已安装环境里的信息,所以不需要重新解析依赖,速度通常比从零创建快很多。但它有两个注意点:
- clone 之后两个环境是完全独立的,之后在备份环境里装任何包都不会影响原环境;
- 如果原环境里有些包是通过 pip 装的,clone 不一定能完美复制,建议 clone 完用
pip list对比确认一下。
导出配置文件的常规做法:
conda activate myenv conda env export > environment.yml编辑environment.yml,它的大致结构是:
name: myenv channels: - conda-forge - defaults dependencies: - python=3.9 - numpy=1.23.4 - pip - pip: - requests==2.28.1这个文件把环境名、channel 来源和每个包的确切版本都记录下来了。注意pip:段,conda env export 会自动把你用 pip 安装的包也写进来,放在pip:子项里,这点很贴心,避免迁移到新机器时丢掉 pip 安装的包。
如果你只想要核心依赖、不想要那些传递依赖和 build 标识,可以加--from-history参数:
conda env export --from-history > environment.yml这样生成的文件只包含你显式conda install过的包,干净很多,适合发到仓库里让别人兼容不同平台。
4.2 从配置文件恢复环境
拿到别人的environment.yml,或者想在自己新机器上重建环境:
conda env create -f environment.yml这个命令会先读取文件的name字段创建环境名,然后按channels顺序去对应 channel 拉取包。这里最容易踩的坑是:environment.yml是从一台特定架构、特定平台机器上导出的,直接拿到另一台机器上执行时,某些包可能找不到对应的二进制包。
我的建议是:跨平台迁移时,尽量用--from-history导出干净的版本,然后在新机器上重新解析。反过来,如果是同一台机器或者同配置机器上的复制,用完整版导出文件则能保证版本完全一致。
恢复完成后,同样跑一下conda env list确认环境创建成功。如果创建中途报 channel 冲突或者版本解析失败,最常见的处理是在创建时临时删除某些严格版本号,或者手动把python的版本改到目标机器可用的版本,比如python=3.8改成python=3.9。
4.3 删除与重命名:conda没给rename,我一般这样做
删除环境:
conda env remove -n myenv执行完之后conda env list里就不会再出现了。这是一个不可逆操作,所以删除前我建议先跑一次conda env export > myenv_backup.yml或者 clone 一份备份,以防某个包版本以后找不回来。
你没看错,conda 没有直接的conda rename命令。要重命名,我一般用两步走:
conda create -n newname --clone oldname conda env remove -n oldname先克隆成新名字,确认新环境能正常激活、包都在,再删除旧环境,既简单又安全。
环境用久了,~/miniconda3/envs/下会积累大量.tar.bz2包缓存和索引缓存,磁盘占用非常大。清理命令:
conda clean --all--all会清理所有未使用的包缓存、索引缓存、临时文件。执行前建议看一眼它会输出的待清理文件列表,确认没问题再继续。这个命令不会动任何已安装的环境本身,只清缓存,所以不用担心环境失效。
5. 下载慢、装包超时:channel配置与加速的实际操作
5.1 channel到底是什么,装包时它按什么顺序工作
channel 就是 conda 的软件仓库,类似 Linux 里的 apt 源、Docker 里的 registry。你执行conda install numpy时,conda 会按照配置的 channel 顺序去一个个仓库里搜索可用的包。
默认情况下,conda 的 channel 是defaults,它由 Anaconda 公司维护。实际使用中大家还经常加conda-forge,这是社区驱动的最大 channel,包更新频率快、覆盖面广,很多小众包只存在于 conda-forge。
在配置文件里设置 channel 的先后顺序非常关键。conda 不是简单地按配置的 URL 列表轮询一个包,而是把这个顺序打包进依赖解析的约束里。如果你在一个环境中既有 defaults 的包又有 conda-forge 的包,很容易出现 A 包来自 conda-forge、B 包来自 defaults,两者依赖的底层库版本不一致,最终导致运行时崩溃。
排查这个问题的方式很简单,看conda list里每一行最后一列:不同 channel 的包混合在一起,就要小心了。
查看当前 channel 顺序:
conda config --show channels5.2 .condarc配置实操:换源不只是改个URL
conda 的配置文件叫.condarc,在用户主目录下。你当然可以手动编辑这个文件,但我更推荐用官方命令来添加 channel,因为命令会自动处理优先级顺序:
conda config --add channels conda-forge conda config --add channels bioconda conda config --set channel_priority strict--add的语义是往 channel 列表最前面添加,所以后 add 的优先级更高。比如先 add conda-forge,再 add bioconda,最终 bioconda 在最前。
channel_priority参数很关键,它有strict、flexible和disabled三档:
strict:严格按 channel 优先级解析,能最大限度避免来自多个 channel 的包混装,但可能解析失败;flexible(默认):允许从低优先级 channel 拿包来满足依赖,但也因此容易产生混装;disabled:只影响显示顺序,不对解析做约束,基本不推荐。
如果你主要在 conda-forge 生态里工作,我建议直接开strict,配合把 conda-forge 设为最高优先级。这样创建新环境时所有包都从 conda-forge 解析,版本兼容性好很多。
你可能也听说过"换源"的说法,本质就是修改.condarc里的channels,把仓库 URL 指向访问速度更快的公共镜像站。常见的公共 conda 镜像源包括清华 TUNA、中科大 USTC、阿里云等,在它们的官网上能查到最新的镜像地址配置方式。这里要注意一点:.condarc里不要写太杂的 channel 列表,源多了之后 conda 每次安装都要依次检查所有源,解析速度和稳定性反而下降。我个人的习惯是只保留一个主要 channel 加 defaults,最多两个。
5.3 还是慢:offline、缓存、超时这几个参数
配置好 channel 之后如果还是觉得慢,先别急着继续改源,按下面顺序排查:
- 看是否卡在
Solving environment(重点检查 channel 数量、依赖复杂度); - 看是否卡在
Downloading(检查网络到具体源的连通性); - 看是否超时报
CondaHTTPError。
如果是网络超时导致的下载失败,可以调大超时时间:
conda config --set remote_read_timeout_secs 120.0 conda config --set remote_connect_timeout_secs 30.0默认超时较短,在弱网环境下频繁中断,调大之后成功率会有明显提升。
还有一种情况:你需要的包其实已经下载过了,可能之前创建过类似环境,conda 缓存里有现成的包。这时可以用--offline强制 conda 只从本地缓存查找,不访问网络:
conda create -n myenv python=3.9 --offline这个命令在网络故障时能救急,但如果缓存里确实没有对应包,它会很快报错。需要注意--offline只适用于创建环境,日常conda install也有对应的--offline,用法相同。
清理策略上,我建议定期conda clean --all,清理缓存能让后续下载逻辑更清晰。但注意清理完缓存后,下次创建环境需要重新下载所有包,所以在网速慢的环境里不要过度清理。
6. 多版本Python、CUDA版本隔离与IDE联动
6.1 多版本Python共存是Conda的核心优势
Conda 最让我离不开的,是它可以同时存在多个 Python 版本,各版本互不干扰。这在项目多的环境里几乎是救命稻草。
conda create -n py39 python=3.9 -y conda create -n py311 python=3.11 -y conda activate py39 python --version conda activate py311 python --version你可以在py39里跑老项目,在py311里调试新代码,两条线互不影响。每个环境的 Python 解释器都是独立的二进制文件,不存在"系统里装了多个 Python 导致 PATH 混乱"的问题。
实际使用中我还会用一个小技巧:环境名里直接带 Python 版本和用途,比如py311_ml、py39_web。环境一多,名字不清晰的话,光靠conda env list很难快速找到目标环境。
6.2 在Conda环境里管理CUDA和cuDNN
深度学习场景下,CUDA 版本管理是环境隔离的重头戏。不同框架对 CUDA 版本的要求不同,同一个机器上经常需要同时存在 CUDA 11.7 和 CUDA 12.1 的环境。
在 conda 里,通过安装指定版本的cudatoolkit和cudnn即可实现:
conda create -n tf2 python=3.9 -y conda activate tf2 conda install cudatoolkit=11.2 cudnn=8.1安装完成后,进入环境里的python,通过以下代码确认实际版本:
import tensorflow as tf print(tf.test.is_gpu_available())值得注意的是,PyTorch 从较新的版本开始,官方推荐直接用 pip 安装带 CUDA 支持的轮子包,也就是 CUDA 运行时已经包含在包内部,不再单独依赖 conda 的cudatoolkit。这种场景下你需要做的是直接看官方文档给的安装命令,比如pip install torch torchvision --index-url某个具体的地址,而不是自己手动在 conda 里装 CUDA。
简而言之,判断标准是:框架有没有在 wheel 包里内置 CUDA。如果内置了,你只需要保证系统显卡驱动版本足够新,不需要管 conda 里的 cuda 相关包;如果没有内置,你才需要手动conda install cudatoolkit和cudnn。
创建新环境时,不要图省事把所有和 CUDA 相关的包都默认装上,先确认项目需要哪个版本。装错了版本轻则无效,重则导致框架运行时报libcudart.so找不到这类错误。
6.3 PyCharm/VS Code如何挂到conda环境
很多人在命令行里把环境管得井井有条,一打开 IDE 却用的是系统默认解释器,最后跑出来的代码和命令行结果完全不一样,排查半天才发现解释器选错了。
PyCharm 里配置 conda 环境的路径:
File -> Settings -> Project -> Python Interpreter- 点击齿轮图标选择
Add Interpreter - 选
Conda Environment -> Existing environment - 在
Interpreter框里选择你的环境路径,通常形如~/miniconda3/envs/myenv/bin/python
如果你已经用 conda 激活了目标环境,在 PyCharm 里也可以直接选Conda Environment -> Use existing interpreter,它会自动读取当前 shell 激活的环境。
VS Code 里配置更简单:
- 安装 Python 扩展
- 打开任意 Python 文件,点击右下角的解释器版本号
- 在弹出的列表里选择
Enter interpreter path - 填
~/miniconda3/envs/myenv/bin/python
还有一个小技巧:在 VS Code 的终端里,先执行conda activate myenv再启动 VS Code,它就能自动识别当前激活的环境。比如你在终端里conda activate py39,然后在同一个终端里输入code myproject,VS Code 打开后会默认使用这个环境。
7. 我踩过的conda坑:翻车清单和排查思路
7.1 在base里乱装包的后果
我见过最多的问题,是很多人把base环境当成"全局默认环境",不管什么项目需要什么包,全部一股脑用conda install装到 base 里。
base 环境承载着 conda 自身运行所需的依赖,如果往里面乱塞各种包,尤其是和 conda 自身依赖产生冲突的包,轻则conda update --all时解析失败,重则某种包覆盖了 conda 依赖的底层库,导致 conda 自身报错。
我个人的习惯是:base 保持尽可能干净,只放 conda 和几个基础工具。新建项目一律用独立环境。这样 base 即使出问题,重建成本也很低,不至于把整台开发机搞废。
如果已经在 base 里装了一堆包,想恢复干净状态,最直接的办法是备份environment.yml后直接删除整个 Miniconda 目录重装,而不是试图用命令卸载所有包。卸载依赖链条又长又容易误伤,重装反而更省事。
7.2 conda和pip混用的顺序问题
conda 能装、pip 也能装的包太多了,到底用哪个?我把自己的规则总结成一句话:先 conda,conda 没有或用不了的包再 pip。
原因在于 conda 安装的包不仅带 Python 代码,还带编译好的二进制依赖,它能保证动态链接库版本一致。如果先用 pip 装了一个依赖特定 libstdc++ 版本的包,再用 conda 装一个依赖另一版本的包,两者很可能在运行时因为动态库版本冲突而崩溃,而且这种报错非常隐蔽,往往要到程序运行到某个深层逻辑时才会暴露。
另外还有几个硬性规则:
- 必须在目标环境激活状态下执行
pip install,否则会把包装到其他环境的 site-packages 里; - 不要用
sudo pip install,一旦用了,包会写到系统 Python 的目录里,和 conda 环境完全无关; - 如果某个包在 conda 里装了之后又有新版本出来,优先用 conda 升级,不要直接 pip 覆盖升级,版本来源混了以后
conda list排查问题时会非常痛苦。
当你发现一个包用 conda 和 pip 都装过,但两者版本不一致时,python -c "import 包名; print(包名.__file__)"可以快速查看解释器实际加载的是哪个路径下的包。这个思路可以帮你定位大量"为什么代码和命令行结果不一样"的问题。
7.3 环境目录越来越大,怎么迁移和瘦身
conda 环境用久了,每个环境里都可能残留大量包缓存、解压临时文件和数据。环境数量一多,磁盘占用轻松突破几十 GB。
先看每个环境占了多少空间:
du -sh ~/miniconda3/envs/*/然后清理所有缓存:
conda clean --all如果某个环境已经不需要了,删除之前先确认一下有没有依赖它的项目或脚本:
conda env remove -n old_env环境目录迁移是另一个高频需求。比如系统盘满了,想整体搬到数据盘/data/miniconda3。正确的操作方式不是直接mv目录,因为 conda 的很多配置文件里记录了绝对路径。我推荐的方案是:
- 在新路径下重新安装相同版本的 Miniconda;
- 用
conda env export > envs.yml逐个导出旧环境; - 在新安装的 conda 里用
conda env create -f envs.yml恢复。
如果你实在不想重新安装,用mv之后必须同步修改~/.condarc和所有环境配置文件里的绝对路径。实测下来非常容易遗漏某个路径,导致某个环境激活正常但 pip 配置失效。
最后再分享一个小技巧
我每次在新环境里都会顺手记一下环境清单:
conda env list conda activate myenv python -V pip list --format=freeze > requirements.txt这不是什么高深操作,但它能让我在几天后回头时快速确认当前环境的状态。尤其是你同时维护多个项目时,一张清晰的环境清单比任何记忆都可靠。
把 conda 当成一个"环境管理工具"而不是"装包工具",你的很多困惑会迎刃而解。遇到报错时先拆解它在哪个环节出错——是 shell 没初始化、channel 没配好、依赖解析失败,还是磁盘空间不足?按这个思路排查,基本能自己解决九成以上的问题。