macOS Conda 环境 Python 版本切换失败问题排查

最近在使用 conda 管理 Python 环境时,遇到了一个诡异的问题:明明已通过 conda activate 切换到目标环境,但运行 python --version 时版本仍显示 Homebrew 安装的 3.13.1,而非 conda 环境中指定的 3.11.x。经过一番折腾,最终确认是 PATH 路径冲突 导致的。

问题现象

激活 conda 环境后,系统仍优先调用了 Homebrew 的 Python。

原因分析

1. Python 别名干扰

通过 which python 发现,python 命令被别名指向了 Homebrew 的路径 /opt/homebrew/bin/python3。这种别名会直接覆盖 conda 环境的路径优先级,导致环境切换失效 。

2. PATH 路径顺序问题

conda 环境依赖 PATH 环境变量的优先级。正常情况下,激活环境后,conda 会将当前环境的 bin 目录(如 /opt/anaconda3/envs/pandas/bin)添加到 PATH 的最前面。但如果 Homebrew 的路径(/opt/homebrew/bin)在此之上,系统仍会优先调用全局安装的 Python 。

解决方案

步骤 1:移除 Python 别名

检查并删除 ~/.zshrc~/.bash_profile 中的 Python 别名配置:

unalias python  # 临时移除当前会话的别名  

若希望永久生效,需手动编辑配置文件,删除类似 alias python='/opt/homebrew/bin/python3' 的行 。

步骤 2:调整 PATH 顺序

确保 conda 环境路径在 Homebrew 之前。编辑 ~/.zshrc,添加以下内容:

# 优先加载 conda 环境路径  
export PATH="/opt/anaconda3/envs/pandas/bin:$PATH"  

保存后运行 source ~/.zshrc 使配置生效 。

步骤 3:验证 conda 初始化

运行 conda init zsh 确保 conda 能正确管理 shell 环境变量。检查 ~/.zshrc 是否包含 conda 的自动加载脚本:

# >>> conda initialize >>>  
__conda_setup="$('/opt/anaconda3/bin/conda' 'shell.zsh' 'hook' 2>/dev/null)"  
eval "$__conda_setup"  
# <<< conda initialize <<<  

若未初始化,conda 无法动态调整 PATH

验证结果

完成上述步骤后,重新激活环境并检查 Python 版本:

conda activate pandas  
which python  # 应显示 conda 环境路径,如 /opt/anaconda3/envs/pandas/bin/python  
python --version  # 应显示 Python 3.11.x  

总结

此次问题的核心是 环境变量冲突。通过清理别名、调整 PATH 顺序并确保 conda 正确初始化,即可解决版本切换失败的问题。


macOS 使用 Colima 运行 Docker

Colima是一个免费的开源容器运行时,它使用QEMU在虚拟机中运行Docker容器。它是由Lima Project创建的,Lima项目是一群致力于创建工具以方便在 macOS上运行容器化应用程序的开发人员。

Lima (Linux virtual machines (on macOS, in most cases)) 项目由一群MacBook开发人员用户于2019年启动,出于对macOS缺乏良好的容器运行时和工具的不满而DIY。当时,在 macOS 上运行Docker容器的唯一选择是适用于macOS的Docker Desktop,它需要大中型公司的许可证。Lima项目着手为macOS创建 Docker Desktop的免费开源替代方案,以提供更好的性能和更多功能。

Colima的主要特点包括:

  • 支持多种芯片架构 - 完美支持搭载Intel和Apple Silicon芯片的Mac设备,以及Linux系统

  • 简单的命令行界面 - 提供直观的CLI操作方式,并采用合理的默认配置

  • 自动端口转发 - 智能处理容器端口映射,简化网络配置

  • 卷挂载支持 - 支持在容器和主机之间共享文件系统

  • 多实例管理 - 可以同时运行多个独立的Colima实例

  • 灵活的运行时选择

    - 支持多种容器运行时:

    • Docker(可选择性集成Kubernetes)
    • Containerd(可选择性集成Kubernetes)
    • Incus(支持容器和虚拟机)

在底层实现上,Colima 通过 Lima 启动一个专用的Linux虚拟机来运行容器。

一、安装

brew install colima
brew install docker
brew install docker-compose

注意不要使用brew install docker --cask命令,我们不需要安装图形化界面。

二、启动

colima start --foreground  # 前台运行
brew service start colima  # 后台运行
docker ps -a # 可以执行docker命令了

image-20250503午後71233242

奇怪的是我没办法后台运行,先跳过了(反正前台能运行):

Bootstrap failed: 5: Input/output error
Try re-running the command as root for richer errors.
Error: Failure while executing; `/bin/launchctl bootstrap gui/501 /Users/kelu/Library/LaunchAgents/homebrew.mxcl.colima.plist` exited with 5.

三、停止/删除

停止 Docker 只需要停止 Colima 虚拟机即可:

colima stop # 停止虚拟机
colima start # 启动虚拟机
colima delete # 清理colima,删除虚拟机

四、配置

查看配置:

colima list # 运行的虚拟机

image-20250503午後72801699

colima template

将会打开自定义的配置文件~/.colima/_templates/default.yaml

主要包含以下配置项:

image-20250503午後72157028

五、进阶:运行x86的容器

清理已有的colima

colima stop # 停止虚拟机
colima delete # 清理colima,删除虚拟机

安装qemu

brew install qemu

运行虚拟机

colima start --profile rosetta --cpu 2 --memory 2 --disk 100 --arch x86_64 --vm-type=vz --vz-rosetta --mount-type virtiofs

image-20250504午前113253413

x86_64容器运行

version:  '3.5'

volumes:
  pgdata: {}
  pgdump: {}

services:
  pgsql:
    image: kelvinblood/pgsql:v9.4-alpine
    restart: always
    network_mode: bridge
    container_name: pgsql
    volumes:
      - pgdata:/var/lib/postgresql/data:rw
      - pgdump:/var/lib/postgresql/dump:rw

参考资料


tmux 非常实用的2个快捷键

之前发过了这篇《如何在 tmux 中 kill 掉一个 windows?》,我自定义2个常用的命令:

image-20250503午後64435912

我解绑了 & z mbackspace 键,然后将他们重新分配:

  1. M : 最大化panel和恢复(原本是z)
  2. bspace: 删除窗口

另外还有一个特别常用的快捷键: ], 可以在当前panel下用键盘上下滚动。

unbind-key &
unbind-key z
unbind-key m
unbind-key bspace
bind-key bspace kill-window
bind-key m resize-pane -Z

然后重新加载:

tmux source-file ~/.tmux.conf

macOS 的一些内存泄露进程

目前一共遇到了3个,以后可以慢慢补充进来:

  1. idleassetsd

    看我这篇:《macOS 每秒钟强杀 idleassetsd 进程》,跟视频壁纸有关。

  2. Ventura

    我曾经遇到过占用了80G内存,也太疯狂了。网上搜索据说是跟动态壁纸有关,只要使用自己的静态壁纸图片就可以解决。(但我还是用脚本强杀它)

  3. ScreenTimeAgent

    屏幕时间记录的进程,把屏幕时间功能停用就可以了。

我写了个简单的脚本强杀前两个进程,第三个的功能停用之后没遇到问题:

#!/bin/bash

while true; do
    if sudo killall idleassetsd &>/dev/null; then
      echo "idleassetsd ok - $(date '+%m-%d %H:%M:%S')"  # 如果成功,输出 ok
    fi
    if sudo killall Ventura &>/dev/null; then
      echo "Ventura ok - $(date '+%m-%d %H:%M:%S')"  # 如果成功,输出 ok
    fi
    # 等待 1 秒
    sleep 1
done


Windows 10 远程桌面配置

系统版本

  • 必须使用Windows专业版/企业版/教育版
    验证方法:
    设置 > 系统 > 关于 > Windows规格 > 版本

配置流程

步骤一:启用远程桌面

  1. 打开设置面板 Win + I
  2. 导航至 系统 > 远程桌面
  3. 切换开关到”启用”状态

步骤二:防火墙放行设置

快速命令(管理员权限运行):

netsh advfirewall firewall add rule name="Remote Desktop" dir=in protocol=TCP localport=3389 action=allow

图形化设置路径:

  1. 控制面板 > Windows Defender 防火墙
  2. 选择允许应用通过防火墙
  3. 勾选”远程桌面”专用/公用网络权限
  4. 确认保存更改

性能优化建议

  • 调整显示设置降低带宽消耗
  • 启用硬件加速(支持GPU的机器)
  • 使用有线网络连接

使用Python脚本防止系统休眠与锁屏

什么是pyautogui?

pyautogui 是一个跨平台的Python库,允许开发者通过代码控制鼠标、键盘以及进行屏幕图像识别。它用简单的语法模拟人类对计算机的操作,适合快速实现轻量级自动化任务,比如防止系统休眠、批量处理重复操作等。

核心功能速览

  1. 鼠标控制
    • 移动光标:moveTo(x, y)
    • 点击操作:click()
    • 拖动对象:dragTo(x, y)
    • 实时获取光标位置:position()
  2. 键盘操作
    • 输入文本:typewrite("Hello!")
    • 单次按键:press('enter')
    • 组合快捷键:hotkey('ctrl', 'c')
  3. 屏幕交互
    • 截图保存:screenshot('screen.png')
    • 图像定位:locateOnScreen('button.png') (通过图像匹配坐标)

如下:

import time
import pyautogui

def main():
    MAX_RUNTIME = 3600 * 8  # 8小时自动停止
    start_time = time.time()
    while time.time() - start_time < MAX_RUNTIME:
        pyautogui.moveRel(1,1)
        # pyautogui.press('press')
        pyautogui.press('esc',interval=0.5)
        pyautogui.scroll(1)
        pyautogui.hotkey('ctrl','f')
        current_time = time.strftime("%Y-%m-%d %H:%M:%S")
        print(f"移动:{current_time}")
        time.sleep(100)

if __name__=="__main__":
    main()

把 Windows 的 bat 文件固定在任务栏

我用常规方式无法将.bat脚本快捷方式固定到Windows任务栏。这里介绍通过伪装资源管理器进程绕过限制。

步骤

1. 创建特殊快捷方式

# 右键桌面 → 新建快捷方式 → 输入:
explorer.exe "D:\scripts\your_script.bat"

2. 固定到任务栏

  • 拖动该快捷方式至任务栏
  • 系统将识别为文件资源管理器项而非脚本

技术原理

  • explorer.exe代理执行:通过资源管理器宿主进程加载脚本,规避控制台进程限制
  • 任务栏缓存机制:系统仅校验首次固定时的宿主程序(explorer.exe)

注意事项

  • 路径含空格时必须用英文引号包裹