只运行一个python程序(如Firefox)?

时间:2011-08-09 06:53:08

标签: python firefox google-chrome process

当我打开Firefox时,请运行命令:

firefox http://somewebsite

url在Firefox的新标签页中打开(同样的事情也发生在Chromium上)。有没有办法在Python中复制这种行为?例如,调用:

processStuff.py file/url

然后打电话:

processStuff.py anotherfile

不应该启动两个不同的进程,而是向当前正在运行的程序发送消息。例如,您可以在一个选项卡式对话框中使用信息,而不是10个单个窗口。

为能够描述如何 Firefox / Chromium以跨平台方式执行此操作的任何人添加赏金。

5 个答案:

答案 0 :(得分:24)

Firefox的方式是:第一个实例创建一个套接字文件(或Windows上的命名管道)。这既可以作为Firefox的下一个实例检测第一个实例并与之通信的方式,也可以在死亡之前将其转发给URL。套接字文件或命名管道只能从本地系统上运行的进程访问(如文件所示),没有网络客户端可以访问它。由于它们是文件,防火墙也不会阻止它们(就像在文件上写一样)。

这是一个天真的实现来说明我的观点。首次启动时,会创建套接字文件lock.sock。进一步启动脚本将检测锁并将URL发送给它:

import socket
import os

SOCKET_FILENAME = 'lock.sock'

def server():
    print 'I\'m the server, creating the socket'
    s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
    s.bind(SOCKET_FILENAME)

    try:
        while True:
            print 'Got a URL: %s' % s.recv(65536)
    except KeyboardInterrupt, exc:
        print 'Quitting, removing the socket file'
        s.close
        os.remove(SOCKET_FILENAME)

def client():
    print 'I\'m the client, opening the socket'
    s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
    s.connect(SOCKET_FILENAME)
    s.send('http://stackoverflow.com')
    s.close()

def main():
    if os.path.exists(SOCKET_FILENAME):
        try:
            client()
        except (socket.error):
            print "Bad socket file, program closed unexpectedly?"
            os.remove(SOCKET_FILENAME)
            server()
    else:
        server()

main()

你应该实现一个合适的协议(发送适当的数据报而不是硬编码长度),也许使用SocketServer,但这超出了这个问题。 Python Socket Programming Howto也可能对您有所帮助。我没有Windows机器,所以我无法确认它是否适用于该平台。

答案 1 :(得分:8)

您可以创建一个数据目录,在程序运行后,在检查文件是否不存在之后创建“锁定文件”。

如果存在,您应该尝试与现有进程通信,该进程创建套接字或管道或类似的东西,并以适当的方式传达其地址或路径。

有许多不同的方法可以执行此操作,具体取决于程序运行的平台。

答案 2 :(得分:2)

虽然我怀疑Firefox / Chrome是如何做到这一点的,但是可以使用套接字归档您的目标并仅依赖于文件系统。我发现很难投入到文本中,因此请参阅下面的粗略流程图,了解如何完成。我会认为这种方法类似于cookie :)。最后一个想法是,通过这种方式,可以跨多个会话存储工作空间或选项卡。

修改
根据注释,不会在进程之间共享环境变量。到目前为止,我所有的工作都是一个调用多个模块的过程。抱歉有任何困惑。

File System Message Relay

答案 3 :(得分:2)

我认为您可以使用multiprocessing connectionssubprocess来完成此操作。您的脚本只需要尝试连接到localhost上的“远程”连接,如果它不可用,则可以启动它。

答案 4 :(得分:1)