You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Python脚本向命令行运行的可执行程序发送数据

Python与Stockfish进程基于UCI协议交互实现方案

你之前使用os.startfile启动可执行文件的方式无法获取进程的输入输出句柄,无法实现双向数据交互,改用Python标准库subprocess模块启动子进程并绑定标准输入、输出管道即可解决问题,该方案完全基于原生交互,不需要依赖任何第三方国际象棋库,符合你从零实现UCI协议功能的需求。

完整实现代码

1. 导入依赖并初始化Stockfish子进程

import subprocess

# 替换为你本地的Stockfish可执行文件路径
STOCKFISH_PATH = r"C:\your\path\to\stockfish.exe"

# 启动Stockfish子进程,绑定输入输出管道
stockfish_process = subprocess.Popen(
    STOCKFISH_PATH,
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    text=True,  # 自动处理字符串编解码,无需手动转换bytes
    bufsize=1  # 开启行缓冲,写入带换行的内容会自动发送,无需手动flush
)

2. 实现指令发送函数

def write_command_to_terminal(command: str):
    # UCI协议要求每条指令末尾必须加换行符,Stockfish才会识别为完整指令
    stockfish_process.stdin.write(command + "\n")
    # 如果未配置bufsize=1,需要手动调用flush确保数据发送到子进程
    # stockfish_process.stdin.flush()

3. 主逻辑实现

if __name__ == "__main__":
    command = ""
    while command != "end":
        command = input("Type command, type end to finish: ")
        if command != "end":
            write_command_to_terminal(command)
            # 以下为可选逻辑:读取Stockfish的返回结果
            while True:
                output = stockfish_process.stdout.readline().strip()
                print(f"Stockfish返回:{output}")
                # 按照UCI协议约定匹配返回结束标记,避免无限阻塞
                # 可根据实际发送的指令调整判断条件,比如发送go指令后匹配bestmove开头的返回
                if output in ("uciok", "readyok") or output.startswith("bestmove"):
                    break
    # 程序结束时主动终止Stockfish子进程
    stockfish_process.terminate()

注意事项

  • 必须严格遵循UCI协议规范发送指令,所有指令末尾必须加换行符,否则Stockfish会持续等待指令输入不会返回结果
  • 读取返回结果时必须根据发送的指令匹配对应的结束标记,不能无限制读取,否则会发生线程阻塞
  • 路径包含特殊字符或在Windows环境下时,建议给路径字符串加r前缀避免转义符解析错误

内容的提问来源于stack exchange,提问作者Mitchnoff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 02:54:04