2012-06-16 41 views
1

我想编写一个基于控制台的包装来启动程序,除非我尝试使用'urxvt -e myscript'或某些变体来运行它,否则它可以正常工作。例如:python中的后台进程在终端上使用-e选项

test.py

#!/usr/bin/python2.7 
import subprocess 

print 'Press enter to launch' 
raw_input() 

subprocess.Popen(['firefox']) 

如果我在./test.py终端上运行这一点,它按预期工作。 Firefox启动,脚本存在。但是如果我用'urxvt -e ./test.py'来试试这个脚本,那么脚本会打开,运行并启动Firefox。但是当脚本退出时,firefox被杀死了。

如何使用'term -e script'运行脚本时如何启动程序,以便在脚本退出时不会导致它死亡。

编辑:更清楚: 我想启动一个运行python脚本的新终端。脚本完成它的任务并启动程序。然后脚本退出,终端关闭,程序继续运行。

回答

1

当测试这个时,我发现结果高度依赖于要启动的程序,而且这个问题与python无关。我从来没有注意到它,但'term -e program'只适用于某些程序,其他程序则以我得到的行为退出。有些程序不保留继承的pid/sid,而有的则不保留。

例如

>>> print os.getpid() 
3556 
>>> os.execl('/usr/bin/gvim', 'gvim') 

快速 'PS -e' 示出

3556 pts/1 00:00:00 gvim <defunct> 
3557 ?  00:00:00 gvim 

当发射终端关闭时,具有相同SID关闭所有进程。所以'gvim已经失效'消失了,但另一部分仍然存在。当启动终端关闭时,没有获得新的pid/sid的程序将退出。解决方案是在这个过程中强制一个新的sid。

import os 

if os.fork(): 
    # parent 
    do_stuff() 

else: 
    # child 
    os.setsid() 
    os.execl('prog', 'prog') 
0
import os 

print 'Press enter to launch' 
raw_input() 

if os.fork(): 
    # Parent 
    print 'clean up' 
    raw_input() 

else: 
    # Child 
    os.execl('/usr/bin/firefox', 'firefox') 

os.execl用firefox进程替换python进程。

正如你所说的,在subprocess.Popen中,当脚本结束时,firefox子进程被终止。

随着os.execl,脚本本身并没有结束。它被替换为不立即结束(并且不会被终止)的firefox进程。一旦达到了os.execl命令,它的行为就好像您称为term -e firefox一样。

+0

这更接近我想要的,但我意识到我并不完全清楚我想要的行为。我已经更新了操作。有了这个,终端在启动ff后不会关闭,并且在该任务被杀的时候ff仍然会退出。另外,在启动程序后,我确实需要做一些清理工作,所以程序启动时停止脚本是一个nogo。 – kalhartt

+0

@kalhartt:嗯。在Ubuntu 11.10上,终端*在启动ff后关闭,而ff不*退出。无论如何,因为你需要在启动ff之后做一些清理*,我已经添加了一些代码来展示如何分叉原始进程,这样你就可以在一个进程中启动ff并在另一个进程中进行清理。 – unutbu

+0

我在archlinux上运行,有趣的是它有不同的行为。即使这个当前的例子不适合我。但是分叉是正确的路径,我只需要在os.execl之前添加os.setsid(),它的效果非常好!谢谢你的一切。 – kalhartt

1

将符号符号(&)添加到您启动的命令中。

subprocess.Popen(['firefox &']) 
+0

使用['firefox&']时,脚本退出后,Firefox仍会死亡。所以这不适合我。 – kalhartt

+0

这不起作用。当父进程被终止时,子进程将被终止。 – 2012-06-17 01:00:18

相关问题