使用os.popen().read()调用rofi时遇ValueError: embedded null byte错误求助
解决rofi管道传递带图标播客条目时的
ValueError: embedded null byte错误 问题根源
你碰到的这个错误,核心原因是你把包含\x00(null字节)的字符串直接拼到了shell命令里。shell的命令参数是基于C语言字符串实现的,而C语言里字符串是以null字节结尾的——当shell看到命令里的第一个\x00时,会直接把后面的内容截断,这就导致os.popen底层依赖的subprocess模块抛出了embedded null byte的错误。
你的代码逻辑本身是对的:rofi确实支持用\x00icon\x1f<图标路径>的格式给条目指定图标,但错在你用heredoc把带null的内容塞进了shell命令字符串里,而不是直接把内容传给rofi的标准输入。
修复方案
把os.popen的写法换成subprocess.Popen,直接通过进程的标准输入传递包含null字节的podcasts_list,完全绕开shell处理null字节的问题。修改后的代码如下:
import os from subprocess import Popen, PIPE # 新增导入 def show_podcasts(f): podcasts_list = "" with open(f,"r") as podcasts: for line in podcasts: episode_title = " ".join(line.split(" ")[:-2]) found = False for pic in os.listdir("images"): pic_path = os.path.join("images", pic) if os.path.isfile(pic_path): if pic.startswith(episode_title): found = True # 用完整路径避免rofi找不到图标 podcasts_list += f"{episode_title}\x00icon\x1f{pic_path}\n" if not found: podcasts_list += episode_title + "\n" # 替换原来的os.popen调用 rofi_proc = Popen( ["rofi", "-dmenu", "-p", "enter the podcast you are looking for"], stdin=PIPE, stdout=PIPE, text=True ) selected_podcast, _ = rofi_proc.communicate(input=podcasts_list) # 处理选中结果,去除多余换行 selected_podcast = selected_podcast.strip()
额外优化点
- 我把图标路径改成了完整路径
pic_path,避免rofi因为工作目录问题找不到图标文件; - 用
subprocess直接调用命令的方式,还能避免播客标题里包含特殊字符(比如$、|、")时触发的shell注入风险,比原来的写法更安全。
内容的提问来源于stack exchange,提问作者javi3y
相关产品推荐
相关产品推荐

