如何强制旧版本的eog在新实例中运行?

时间:2011-09-18 22:21:48

标签: python image popen sh

我有一个小的python脚本,我通过将它们写入临时文件来显示图像,在临时文件上调用eog,然后在eog进程关闭后在临时文件上调用rm。相关代码看起来基本上是这样的:

os.popen('(eog --new-instance tmp.jpg; rm tmp.jpg)&')

--new-instance标志很重要;没有它,如果已经有一个eog进程,eog调用只是告诉预先存在的eog进程显示tmp.jpg并立即返回。 rm在预先存在的eog进程打开tmp.jpg之前执行。然后预先存在的eog进程崩溃。

不幸的是,我无法完全控制我使用此脚本的某些系统。其中一些安装了过时的eog版本,不支持--new-instance,我不想烧掉我的配额空间来构建本地副本。

我是否有某种方式可以启动eog以防止它检测是否有其他实例?或者是否有另一种可靠的策略在复杂的查看器中显示图像(即支持缩放,平移等),这些策略不会使我的目录与临时文件混乱?

2 个答案:

答案 0 :(得分:0)

总体而言,可能有更好的方法可以做到这一点,但如果您想确保rmeog完成之前未运行,则可以使用wait() Popen对象。这将解决您的崩溃问题,但您还需要检查现有的eog进程是否正在运行。

import subprocess as subp
import os, signal
findInstance = subp.check_output('ps -eaf | grep eog', shell=True).strip()
for line in findInstance.decode('utf-8').split('\n'):
    if line.split()[7] == 'eog':
        os.kill(int(line.split()[1]), signal.SIGKILL)
subp.Popen(['eog','tmp.jpg']).wait()
subp.Popen(['rm','tmp.jpg'])

这会查找eog进程,如果找到它,则会终止它。然后,它重新生成eog,它可以显示新图像,并在删除临时图像之前等待eog完成。

答案 1 :(得分:0)

eog按名称监控文件,因此您无法打开图像,然后安全地取消链接。

您可以在删除文件之前引入延迟:

#!/usr/bin/env python
import os
import subprocess
import tempfile
import time

from threading import Thread

def write_image_to(f):
    f.write(open(os.path.expanduser('~/Pictures/lenaNN.jpg'), 'rb').read())

def f(write_image_to, delay=None):
    with tempfile.NamedTemporaryFile() as fileobj:
        write_image_to(fileobj)
        fileobj.flush() # ensure writing to disk

        r = subprocess.call(['eog','--new-instance',fileobj.name],close_fds=True)
        if r: # eog don't support new-instance
           subprocess.call(['eog', fileobj.name], close_fds=True)
           if delay:
              time.sleep(delay)

for _ in xrange(10): 
    Thread(target=f, args=(write_image_to, 3600)).start()

为避免等待延迟过期,您可以在后台调用脚本:

$ python your_script.py & disown

disown确保在您注销后脚本继续有效。