【Bug已解决】Claude Code 多实例冲突:Port conflict 与 PID file lock 的 settings.json 配置解法 1. 多实例冲突到底卡在哪Port conflict 与 PID file lock 的真实场景Claude Code 同时开两个实例第二个直接报Another Claude Code instance is already running (PID: 12345)或者换了个报错EADDRINUSE: address already in use :::5555这是本地多项目并行开发者最常撞上的两类拦路虎。前者是 PID file lock后者是 Port conflict本质都是 Claude Code 在启动时做了一次单例检查——它默认认为同一台机器上只应该跑一个实例于是用 PID 文件和本地端口做了互斥保护。这个设计在单人单项目时很省心但一旦你进入多显示器多终端、tmux 多窗口、后台任务没退干净就开新实例、CI/CD 并发跑任务这些场景它就从保护变成了阻碍。更隐蔽的是会话串扰两个实例共享同一个~/.claude/sessions/目录你在终端 1 敲的命令出现在终端 2 的上下文里--continue恢复到了另一个项目的会话排查起来非常费劲。这篇内容面向的就是我想同时跑多个 Claude Code但不想被锁和端口拦住的开发者。我会给出可复制的settings.json骨架、--force启动参数组合以及端口检测、锁文件清理、多实例验证三步动作。如果你还没配好 API 访问层可以先去 TaoToken 模型对话 把模型通道跑通再回来处理多实例问题顺序会更顺。先把冲突的三种典型表现列清楚方便你对号入座报错/现象根因触发场景Another Claude Code instance is already running (PID: xxx)PID file lock旧进程残留、后台未退出EADDRINUSE: address already in use :::5555Port conflictMCP Server 端口被占终端 1 操作出现在终端 2会话文件共享同一CLAUDE_CONFIG_DIR启动后立刻退出、无报错锁文件损坏异常 kill 后 PID 文件未清理解这张表后面的每一步操作你都知道自己在解决哪一类问题而不是盲目敲命令。2. 前置准备用 TaoToken 打通模型通道并确认 Claude Code 版本在折腾多实例之前先确认你的 Claude Code 能正常发起请求。多实例冲突是启动层的问题如果模型通道本身没通你会把两类问题混在一起排查效率极低。TaoToken 在这里的角色是统一的模型访问入口。你不需要在每台机器、每个实例里分别配置不同的上游地址而是让所有 Claude Code 实例都指向同一个 API 端点这样多实例之间的差异只体现在配置目录和端口上模型通道保持一致。官网入口在 taotoken.netAPI 基址是https://taotoken.net/api。第一步确认 Claude Code 版本不同版本对--force和--port的支持略有差异claude --version # 输出示例claude-code 1.x.x第二步配置 API Key。去 TaoToken API Keys 页面 生成一个 Key然后写入环境变量。建议写进 shell 配置文件避免每个终端重复设置# 写入 ~/.bashrc 或 ~/.zshrc export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_API_KEYsk-你的TaoToken密钥 # 生效 source ~/.zshrc第三步验证单实例能跑通。这一步很关键它把模型通道问题和多实例冲突问题彻底分开claude --print 回复 OK 两个字母即可 --max-turns 1 # 期望输出OK如果这一步失败先去看 TaoToken 接入文档 排查鉴权和基址问题不要往下走。只有单实例稳定了多实例的排查才有意义。注意ANTHROPIC_BASE_URL结尾不要带/v1Claude Code 会自己拼接路径。多实例场景下这个变量应该保持一致不要每个实例指向不同地址否则会话串扰排查会多一层干扰。3. 可复制配置settings.json 骨架与 --force 启动参数组合这一节是核心。多实例冲突的解法不是每次都手动 kill而是用配置把每个实例隔离到独立的命名空间。Claude Code 支持通过CLAUDE_CONFIG_DIR环境变量指定配置目录PID 文件、会话文件、settings.json 都会落在该目录下天然隔离。先看settings.json的骨架。这个文件放在每个实例自己的配置目录里内容可以基本一致关键是路径要独立{ permissions: { allow: [ Read, Edit, Bash(git status), Bash(git diff) ], deny: [] }, env: { ANTHROPIC_BASE_URL: https://taotoken.net/api }, mcpServers: { local-tools: { command: npx, args: [-y, your/mcp-server], env: { PORT: 5561 } } } }注意mcpServers里的PORT字段。MCP Server 是 Port conflict 的高发区因为很多 MCP 实现默认监听固定端口。给每个实例的 MCP Server 分配不同端口是避免EADDRINUSE的第一道防线。接下来是启动脚本。我建议为每个实例写一个包装脚本把配置目录、端口、工作目录一次性固定下来#!/usr/bin/env bash # 保存为 ~/bin/claude-inst1.sh export CLAUDE_CONFIG_DIR$HOME/.claude-instance1 export ANTHROPIC_BASE_URLhttps://taotoken.net/api mkdir -p $CLAUDE_CONFIG_DIR cd $HOME/project1 || exit 1 claude --force --port 5561 $第二个实例只需要改三处CLAUDE_CONFIG_DIR换成instance2--port换成5562cd到project2。--force的作用是忽略 PID 文件锁强制启动适合你确认没有其他实例在跑、但锁文件残留的情况。#!/usr/bin/env bash # 保存为 ~/bin/claude-inst2.sh export CLAUDE_CONFIG_DIR$HOME/.claude-instance2 export ANTHROPIC_BASE_URLhttps://taotoken.net/api mkdir -p $CLAUDE_CONFIG_DIR cd $HOME/project2 || exit 1 claude --force --port 5562 $给脚本加执行权限chmod x ~/bin/claude-inst1.sh ~/bin/claude-inst2.sh如果你不想写脚本也可以直接在终端里用一行命令组合。下面这个写法把配置目录和端口都内联进去适合临时开一个实例CLAUDE_CONFIG_DIR~/.claude-instance3 claude --force --port 5563参数对照表如下方便你按需组合参数/变量作用多实例建议CLAUDE_CONFIG_DIR指定配置目录每个实例唯一--force忽略 PID 文件锁确认无其他实例时使用--port指定本地端口每个实例唯一避开 5555ANTHROPIC_BASE_URL模型 API 基址所有实例保持一致工作目录cd项目隔离每个实例不同项目提示--force不会杀掉正在运行的实例它只是跳过锁检查。如果你不确定是否有实例在跑先执行ps aux | grep claude | grep -v grep看一眼再决定是否加--force。4. 验证请求端口检测、锁文件清理、多实例三步动作配置写好了接下来是验证。我把它拆成三步动作每步都有明确的成功判据避免看起来启动了但其实串扰。第一步端口检测。在启动第二个实例前先确认目标端口空闲# macOS / Linux 通用 lsof -i :5562 # 或者用 netstat netstat -tulpn 2/dev/null | grep 5562如果lsof有输出说明端口被占先找到占用进程lsof -t -i :5562 # 输出一个 PID比如 23456 kill 23456或者干脆换一个端口--port 5564即可。端口检测这一步能挡掉大约四分之一的启动失败。第二步锁文件清理。PID 文件默认在配置目录下路径形如$CLAUDE_CONFIG_DIR/claude.pid。异常退出后它可能残留导致下次启动误判# 查看锁文件 ls -la ~/.claude-instance1/claude.pid # 确认没有对应进程后删除 rm -f ~/.claude-instance1/claude.pid清理前务必用ps aux | grep claude确认没有活跃进程否则删了锁文件可能让两个实例同时写同一份会话。第三步多实例验证。同时启动两个实例然后做交叉检查# 终端 1 ~/bin/claude-inst1.sh --print 记住数字 111 --max-turns 1 # 终端 2 ~/bin/claude-inst2.sh --print 记住数字 222 --max-turns 1两个都返回结果后检查进程和端口是否各自独立ps aux | grep claude | grep -v grep # 应该看到两个进程PID 不同 lsof -i :5561 lsof -i :5562 # 各自监听自己的端口再验证会话隔离。在实例 1 里执行--continue确认恢复的是实例 1 的会话而不是实例 2 的CLAUDE_CONFIG_DIR~/.claude-instance1 claude --continue --print 刚才让你记的数字是多少 --max-turns 1 # 期望输出111如果输出 222说明两个实例共享了会话目录回去检查CLAUDE_CONFIG_DIR是否真的不同。这一步是会话串扰的终极判据。5. 本篇常见错排查从 EADDRINUSE 到会话串扰的定位路径即使按上面的步骤做了还是可能踩坑。这一节把高频错误和定位方法列出来你遇到报错可以直接对照。EADDRINUSE: address already in use :::5555反复出现但你lsof -i :5555又查不到进程。这种情况通常是 MCP Server 的子进程还在父进程退了子进程没退。用lsof -i :5555 -sTCP:LISTEN加上监听状态过滤或者直接pkill -f mcp-server清掉残留。Another Claude Code instance is already running但ps aux里根本没有 claude 进程。这是典型的 PID 文件残留直接删锁文件即可。如果删了还报检查CLAUDE_CONFIG_DIR是否指向了只读目录导致新锁文件写不进去。两个实例启动都成功但--continue总是恢复到同一个会话。九成是CLAUDE_CONFIG_DIR没生效可能被 shell 里的其他 export 覆盖了。用echo $CLAUDE_CONFIG_DIR在每个终端里确认一下注意子 shell 和 tmux 窗口的环境变量是独立的。--force加了还是启动失败。检查是不是端口冲突而不是锁冲突--force只解决 PID 锁不解决端口占用。两个问题要分别处理。CI/CD 里多个任务并发跑 Claude Code互相抢锁。用flock做串行化flock /tmp/claude.lock claude --print 任务内容 --max-turns 10flock会等锁释放再执行天然避免并发冲突。如果你需要真正的并行而不是串行那就给每个 CI 任务分配独立的CLAUDE_CONFIG_DIR和端口思路和本地多实例一致。排查清单速查现象优先检查命令启动报 PID 锁锁文件残留rm -f $CLAUDE_CONFIG_DIR/claude.pid启动报端口占用端口监听lsof -i :PORT会话串扰配置目录echo $CLAUDE_CONFIG_DIR进程残留活跃进程ps aux | grep claudeCI 并发冲突文件锁flock /tmp/claude.lock注意多实例操作同一份代码文件时即使配置隔离了文件写入仍会冲突。确保每个实例处理不同的项目目录或者用 git 分支隔离。6. 长期多实例方案Coding Plan 与配置目录规范如果你只是偶尔开两个实例上面的脚本够用了。但如果你是长期多项目并行建议把配置目录规范固定下来形成一套可维护的目录结构~/.claude-instances/ ├── project-a/ │ ├── settings.json │ ├── claude.pid │ └── sessions/ ├── project-b/ │ ├── settings.json │ ├── claude.pid │ └── sessions/ └── project-c/ └── ...每个项目一个目录CLAUDE_CONFIG_DIR指向对应路径端口按项目编号递增分配。这样新增项目时只需要复制一份目录、改端口号不需要重新理解整套机制。对于需要长时间跑 Agent 任务、多实例并行的场景可以了解 TaoToken Coding Plan它在模型调用配额和并发上更适合持续性的编码工作流。配合上面的配置目录隔离你可以让多个 Agent 实例各跑各的项目互不干扰。最后给一个我实际在用的启动别名写进~/.zshrc用起来比记脚本路径顺手alias cc1CLAUDE_CONFIG_DIR~/.claude-instances/project-a claude --force --port 5561 alias cc2CLAUDE_CONFIG_DIR~/.claude-instances/project-b claude --force --port 5562 alias cc3CLAUDE_CONFIG_DIR~/.claude-instances/project-c claude --force --port 5563需要哪个项目就敲cc1、cc2端口和配置目录自动隔离。如果启动时报端口占用先lsof -i :5561看一眼大概率是上次没退干净kill掉再启动即可。这套组合我用了几个月多实例冲突基本没再出现过。