如何通过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
相关产品推荐
相关产品推荐

