调用 Claude Code CLI 问题总结
·
调用 Claude Code CLI 问题总结
遇到的问题及解决方案
问题 1: Windows 编码问题
现象:
UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 33: illegal multibyte sequence
原因分析:
- Windows 中文系统默认使用 GBK 编码
subprocess.run(text=True)自动用系统默认编码(GBK)解码输出- Claude CLI 返回 UTF-8 编码内容
- GBK 无法解码 UTF-8 字节序列
解决方案:
# ❌ 错误写法
result = subprocess.run(cmd, capture_output=True, text=True, shell=True)
output = result.stdout # GBK 解码失败
# ✅ 正确写法
result = subprocess.run(cmd, capture_output=True, text=False, shell=True)
output = result.stdout.decode('utf-8', errors='ignore') # 手动 UTF-8 解码
subprocess 模块详解
基本概念
subprocess 是 Python 的标准库模块,用于在 Python 程序中运行外部命令(如 claude、git、npm 等)。
核心用法
import subprocess
# 运行外部命令
result = subprocess.run(
["claude", "--version"], # 命令及参数列表
capture_output=True, # 捕获输出
text=False, # 返回字节(不自动解码)
shell=True # Windows 需要
)
# 获取结果
print(result.returncode) # 返回码(0=成功)
print(result.stdout) # 标准输出
print(result.stderr) # 错误输出
同步 vs 异步调用
同步调用(阻塞,等待完成):
import subprocess
result = subprocess.run(
["claude", "-p", "你好"],
capture_output=True,
text=False,
timeout=60,
shell=True
)
output = result.stdout.decode('utf-8')
异步调用(非阻塞,可并发):
import asyncio
async def call_claude():
# Windows 用 create_subprocess_shell
process = await asyncio.create_subprocess_shell(
"claude -p 你好",
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
)
stdout, stderr = await process.communicate()
output = stdout.decode('utf-8')
return output
# 运行
result = asyncio.run(call_claude())
关键参数说明
| 参数 | 说明 | 推荐值 |
|---|---|---|
capture_output | 是否捕获输出 | True |
text | 是否自动解码为文本 | False(手动解码避免编码问题) |
shell | 是否通过 shell 运行 | True(Windows 需要) |
timeout | 超时时间(秒) | 60、600 等 |
cwd | 工作目录 | 项目路径 |
Windows 特殊处理
问题: Windows 下 subprocess.run(["claude", "..."]) 可能找不到命令
原因:
- Windows 需要通过 shell 解析命令
- 直接调用可执行文件名(如 claude)需要 shell
解决方案:
# ✅ 同步:使用 shell=True
subprocess.run(["claude", "--version"], shell=True)
# ✅ 异步:使用 create_subprocess_shell
await asyncio.create_subprocess_shell("claude --version")
使用 Python 调用 Claude Code CLI 的完整流程
1. 基本调用
import subprocess
# 构建命令
cmd = [
"claude",
"-p", "请分析这段代码",
"--model", "claude-sonnet-4-5-20250929",
"--output-format", "stream-json"
]
# 执行命令
result = subprocess.run(
cmd,
capture_output=True,
text=False, # 字节模式
timeout=60,
shell=True, # Windows 需要
cwd="/path/to/project" # 工作目录
)
# 处理结果
if result.returncode == 0:
output = result.stdout.decode('utf-8', errors='ignore')
print(f"成功: {output}")
else:
error = result.stderr.decode('utf-8', errors='ignore')
print(f"失败: {error}")
2. 异步批量调用(项目分析场景)
import asyncio
async def analyze_batch(files):
"""分析一批文件"""
prompt = f"分析这些文件: {', '.join(files)}"
# 构建命令
cmd = f'claude -p "{prompt}" --model claude-sonnet-4-5-20250929'
# 异步执行
process = await asyncio.create_subprocess_shell(
cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
cwd="/path/to/project"
)
# 等待完成(10分钟超时)
stdout, stderr = await asyncio.wait_for(
process.communicate(),
timeout=600
)
# 解析结果
if process.returncode == 0:
output = stdout.decode('utf-8', errors='ignore')
return parse_json(output)
else:
raise RuntimeError(stderr.decode('utf-8', errors='ignore'))
# 批量处理
async def analyze_project(file_batches):
tasks = [analyze_batch(batch) for batch in file_batches]
results = await asyncio.gather(*tasks, return_exceptions=True)
return results
# 运行
batches = [["file1.java", "file2.java"], ["file3.java", "file4.java"]]
results = asyncio.run(analyze_project(batches))
3. 错误处理最佳实践
try:
result = subprocess.run(
cmd,
capture_output=True,
text=False,
timeout=60,
shell=True
)
if result.returncode != 0:
# 解码错误信息
error = result.stderr.decode('utf-8', errors='ignore')
# 分析常见错误
if "API key" in error:
print("错误:API 密钥未配置")
elif "git-bash" in error:
print("错误:Git Bash 未找到")
elif "not found" in error:
print("错误:Claude CLI 未安装")
else:
print(f"未知错误: {error}")
except subprocess.TimeoutExpired:
print("错误:命令执行超时")
except FileNotFoundError:
print("错误:找不到 claude 命令,请检查 PATH")
except Exception as e:
print(f"错误:{e}")
总结
核心要点
- 编码处理:Windows 下使用
text=False+ 手动 UTF-8 解码 - Shell 支持:Windows 需要
shell=True - 异步处理:大项目分批用
asyncio提高效率 - 错误日志:详细的 DEBUG 输出帮助快速定位问题
subprocess 本质
- 作用:Python 中运行外部命令的桥梁
- 输入:命令、参数、配置
- 输出:返回码、标准输出、错误输出
- 特点:可同步、可异步、可超时、可捕获输出
更多推荐


所有评论(0)