如何使用subprocess模块从Python启动jython程序?

4 投票
1 回答
1501 浏览
提问于 2025-04-16 06:46

我有一个叫做 rajant_server.py 的 jython 服务器脚本,它和一个 Java API 文件互动,用来通过特殊的网络无线电进行通信。我还有一个 Python 程序,它充当客户端(同时还做其他几件事)。目前,我需要先打开一个命令行窗口,输入以下命令来启动服务器:

cd [path to directory containing rajant_server.py
jython rajant_server.py

一旦服务器成功连接,它会等待客户端的连接,而我通过运行以下命令来启动客户端:

cd [path to directory containing python client program]
python main.py

当客户端连接后,服务器会在它的命令行窗口中打印出一些信息(目前是为了调试),而客户端程序也会在它的命令行窗口中打印出调试信息。我想要做的是通过在我的 'main.py' 程序中调用 jython,来简化这个复杂的过程,使用 subprocess 模块。

问题有两个:

1 - 我需要让 rajant_server.py 程序在自己的命令行窗口中打开。

2 - jython 需要在存放 rajant_server.py 文件的目录中运行,换句话说,直接在命令行窗口输入以下命令是行不通的(别问我为什么):

jython C:/code_dir/comm/server/rajant_server.py

但是:

cd C:/code_dir/comm/server
jython rajant_server.py

这样是可以的。


好吧……我刚刚找到了一种方法可以让它工作。看起来有点像是个小窍门,所以我还是希望能有更好的方法。以下是我目前的做法:

serverfile = r'rajant_server_v2.py'
serverpath = os.path.join(os.path.realpath('.'),'Comm',serverfile)
serverpath = os.path.normpath(serverpath)
[path,file] = os.path.split(serverpath)

command = '/C jython '+file+'\n'
savedir = os.getcwd()
os.chdir(path)
rajantserver = subprocess.Popen(["cmd",command],\
        creationflags = subprocess.CREATE_NEW_CONSOLE)

#Change Directory back
os.chdir(savedir)
#Start Client
rajant = rajant_comm.rajant_comm()
rajant.start()

如果你有一个能在 Linux 和 Windows 上都能工作的解决方案,你就是我的英雄。出于某种原因,当我在 subprocess 中添加 creationflags = subprocess.CREATE_NEW_CONSOLE 时,无法更改 stdin 或 stdout 的设置。

1 个回答

1

在subprocess模块中,Popen函数有一个可选的参数'cwd',可以用来设置子进程的当前工作目录。

rajantserver = subprocess.Popen(["cmd",command],\
        creationflags = subprocess.CREATE_NEW_CONSOLE,\
        cwd = path)

这样你就可以省去调用os.getcwd和两个os.chdir的步骤。如果你想在Linux上使用这个脚本,就不能使用'cmd'了。所以你需要用["jython", file]作为Popen的第一个参数。

补充说明:我刚发现,在Linux上运行时,subprocess模块中并没有定义CREATE_NEW_CONSOLE。你可以使用这个:

creationflags = getattr(subprocess,"CREATE_NEW_CONSOLE",0),\

这样做和之前的效果是一样的,只不过当subprocess模块没有定义CREATE_NEW_CONSOLE时,它会使用默认值0。

撰写回答