防止subprocess.call()显示文本
我在使用树莓派(raspbian)时,修改了一个幻灯片脚本,这个脚本是用Python写的,能读取一个PIR运动传感器。
在原来的脚本中,PIR传感器在一段时间内没有检测到运动后,会关闭显示器(HDMI),然后再打开。我想让运动传感器在检测到运动时显示一张新图片。
所以,每当PIR传感器被触发时,我就会调用这个函数:
def new_pic():
sys.stderr.write("\x1b[2J\x1b[H")
myList = []
file = open("dir.txt","rt")
for line in file:
myList.append(line)
file.close()
count = len(myList)
rnd = randint(0,count-1)
current_image = myList[rnd]
current_image = current_image[:-1]
proc = subprocess.Popen(["pgrep", "fbi"], stdout=subprocess.PIPE)
for pid in proc.stdout:
os.kill(int(pid), signal.SIGTERM)
subprocess.call(["fbi", "-noverbose", "-a", "-T", "2", "/home/pi/photoframe/photos/"+current_image])
我在定时任务(crontab)中使用rsync来保持图片库的更新。每次rsync后,我会把文件列表写入' dir.txt'。
这个方法是有效的,唯一的问题是每次加载新图片时,终端的文本会闪现一下。我尝试通过修改-bashrc把提示符改成黑色,并在运行我的Python脚本前执行'clear'命令来解决这个问题。
我现在遇到的问题是:
当调用fbi时,它会显示
using "DejaVu Sans Mono-16", pixelsize=16.67 file=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSansMono.ttf
我试着在fbi命令的末尾添加
> /dev/null
但它并没有理会。
在之前的尝试中,我不断地调用新的fbi实例,但它们会在顶部堆积,最终导致树莓派资源耗尽。另一种方法是跟踪fbi的实例,并在调用下一个实例后结束它们……
我已经在这个问题上绕了好几周了,任何帮助都会非常感激。
后续更新:
第一个回答确实去掉了fbi的输出(subprocess.call)。
现在我看到了一些东西……它闪过得很快——白色的文字在闪烁。
我觉得这和这个if语句有关:
if io.input(PIR_PIN):
if time.time() > (last_flip + SWITCH_TIMER):
new_pic()
每次PIR被触发并且经过足够的时间后,它会被调用8到10次……
我原以为这个时间判断只会让new_pic()被调用一次。last_flip在fbi显示新图片后被设置为当前时间……
我该如何确保new_pic()只被调用一次呢?
谢谢!
安德鲁
1 个回答
根据关于 subprocess 的文档,subprocess 是用来启动另一个程序的,它有一些参数,比如 stdin、stdout 和 stderr,这些参数可以让你把程序的输入输出重定向到其他文件。
默认情况下,这些参数是 None
,这意味着新启动的程序会继承父程序的输入输出文件,这就是为什么它会把文本泄露到你漂亮的界面里的原因。
你可以打开一个文件,甚至可以使用 /dev/null
作为一个黑洞,把输出发送到那里,方法如下:
shutup = open("/dev/null","w")
subprocess.call(["fbi", "-noverbose", "-a", "-T", "2", "/home/pi/photoframe/photos/"+current_image],
stdout=shutup,
stderr=shutup)
另一方面,你可能想要保存输出,并在 Python 中解析它,以确保 fbi 按照预期执行了操作。