如何在Godot 4.6跨平台环境下向fzf --filter传递stdin输入?
在Godot 4.6中跨平台向fzf --filter通过stdin传递大量文件列表
要解决跨平台下给fzf --filter传递大量文件列表的问题,核心方案是使用OS.execute_with_pipe——它支持通过管道向子进程的stdin写入数据,同时读取stdout的结果,既没有输入长度限制,也能兼容Windows、Mac和Linux。
完整实现代码
下面是封装好的工具函数,包含文件遍历、fzf调用、结果读取的完整流程:
# 用fzf筛选文件列表,返回匹配的文件路径数组 func filter_files_with_fzf(filter_query: String, file_list: Array[String]) -> Array[String]: # 初始化管道对应的文件访问对象 var stdin = FileAccess.new() var stdout = FileAccess.new() var stderr = FileAccess.new() # 启动fzf进程,传入过滤参数 var pid = OS.execute_with_pipe("fzf", ["--filter", filter_query], stdin, stdout, stderr) if pid == -1: print_err("无法启动fzf,请确认fzf已安装并添加到系统PATH") return [] # 向fzf的stdin写入文件列表(每行一个文件) stdin.open_from_fd(stdin.get_fd(), FileAccess.WRITE) for file_path in file_list: stdin.print_line(file_path) stdin.close() # 关闭stdin,告知fzf输入结束 # 读取fzf的stdout结果 stdout.open_from_fd(stdout.get_fd(), FileAccess.READ) var filtered_results = [] while not stdout.eof_reached(): var line = stdout.get_line().strip_edges() if line != "": filtered_results.append(line) stdout.close() # 读取错误输出(可选,用于调试) stderr.open_from_fd(stderr.get_fd(), FileAccess.READ) var err_msg = stderr.get_as_text() stderr.close() if err_msg != "": print_warn("fzf错误输出: ", err_msg) # 等待进程结束并检查退出状态 var exit_code = OS.wait_for_process(pid) if exit_code != 0: print_warn("fzf异常退出,代码: ", exit_code) return filtered_results # 跨平台遍历目录,获取所有文件的路径数组 func get_all_files(directory: String) -> Array[String]: var files = [] var dir = DirAccess.open(directory) if dir == null: print_err("无法打开目录: ", directory) return files dir.list_dir_begin(true, true) # 递归遍历、包含隐藏文件 var file_name = dir.get_next() while file_name != "": if dir.current_is_dir(): files += get_all_files(directory + "/" + file_name) else: files.append(directory + "/" + file_name) file_name = dir.get_next() dir.list_dir_end() return files
使用示例
在你的脚本中直接调用上述函数即可:
func _ready(): # 获取当前目录下所有文件 var all_files = get_all_files(".") # 用fzf筛选包含"hi"的文件 var matched_files = filter_files_with_fzf("hi", all_files) print("筛选结果: ", matched_files)
关键注意事项
- fzf环境准备:确保fzf已安装并添加到系统PATH中——Windows可直接下载
fzf.exe放入PATH目录,Mac用brew install fzf,Linux用包管理器安装。 - 管道操作细节:必须手动关闭
stdin,否则fzf会一直等待输入,进程无法结束。 - 跨平台兼容性:用Godot原生的
DirAccess遍历目录,替代依赖shell的find命令,确保Windows、Mac、Linux都能正常运行。 - 无长度限制:相比shell的
<<<输入方式,管道写入没有数据长度限制,支持超大规模文件列表。
内容的提问来源于stack exchange,提问作者jakub




