如何使其与 Windows 兼容?
美好的一天,Stackoverflow!
我在将 Linux 的 Python 脚本之一移植到 Windows 时遇到了一个小(大)问题。令人毛骨悚然的是,我必须启动一个进程并将其所有流重定向到管道中,然后在脚本中对其进行读取和写入。
对于 Linux,这是小菜一碟:
server_startcmd = [
"java",
"-Xmx%s" % self.java_heapmax,
"-Xms%s" % self.java_heapmin,
"-jar",
server_jar,
"nogui"
]
server = Popen(server_startcmd, stdout = PIPE,
stderr = PIPE,
stdin = PIPE)
outputs = [
server_socket, # A listener socket that has been setup before
server.stderr,
server.stdout,
sys.stdin # Because I also have to read and process this.
]
clients = []
while True:
read_ready, write_ready, except_ready = select.select(outputs, [], [], 1.0)
if read_ready == []:
perform_idle_command() # important step
else:
for s in read_ready:
if s == sys.stdin:
# Do stdin stuff
elif s == server_socket:
# Accept client and add it to 'clients'
elif s in clients:
# Got data from one of the clients
服务器套接字、脚本的标准输入和子进程的输出通道(以及输入通道,因为我的脚本将写入该通道)之间的整个 3 路交替,尽管一个不在 select() 列表中)是脚本中最重要的部分。
我知道对于 Windows,win32api 模块中有 win32pipe。问题是找到这个 API 的资源非常困难,而且我找到的资源也没有太大帮助。
我如何利用这个 win32pipe 模块来完成我想要的事情?我有一些来源,它在不同但相似的情况下使用,但这让我很困惑:
if os.name == 'nt':
import win32pipe
(stdin, stdout) = win32pipe.popen4(" ".join(server_args))
else:
server = Popen(server_args,
stdout = PIPE,
stdin = PIPE,
stderr = PIPE)
outputs = [server.stderr, server.stdout, sys.stdin]
stdin = server.stdin
[...]
while True:
try:
if os.name == 'nt':
outready = [stdout]
else:
outready, inready, exceptready = select.select(outputs, [], [], 1.0)
except:
break
stdout
这里是使用 win32pipe 启动的子进程的组合 stdout 和 stderr .popen4(...)
提出的问题是:
- 为什么 Windows 版本不使用
select()
呢?那不行吗? - 如果您在那里不使用
select()
,我如何实现select()
提供的必要超时(显然这里不会像这样工作)
请,帮帮我吧!
Good day, Stackoverflow!
I have a little (big) problem with porting one of my Python scripts for Linux to Windows. The hairy thing about this is that I have to start a process and redirect all of its streams into pipes that I go over and read and write to and from in my script.
With Linux this is a piece of cake:
server_startcmd = [
"java",
"-Xmx%s" % self.java_heapmax,
"-Xms%s" % self.java_heapmin,
"-jar",
server_jar,
"nogui"
]
server = Popen(server_startcmd, stdout = PIPE,
stderr = PIPE,
stdin = PIPE)
outputs = [
server_socket, # A listener socket that has been setup before
server.stderr,
server.stdout,
sys.stdin # Because I also have to read and process this.
]
clients = []
while True:
read_ready, write_ready, except_ready = select.select(outputs, [], [], 1.0)
if read_ready == []:
perform_idle_command() # important step
else:
for s in read_ready:
if s == sys.stdin:
# Do stdin stuff
elif s == server_socket:
# Accept client and add it to 'clients'
elif s in clients:
# Got data from one of the clients
The whole 3 way alternating between a server socket, stdin of the script and the output channels of the child process (as well as the input channel, as my script will write to that one, although that one is not in the select() list) is the most important part of the script.
I know that for Windows there is win32pipe in the win32api module. The problem is that finding resources to this API is pretty hard, and what I found was not really helpful.
How do I utilize this win32pipe module to do what I want? I have some sources where it's being used in a different but similar situation, but that confused me pretty much:
if os.name == 'nt':
import win32pipe
(stdin, stdout) = win32pipe.popen4(" ".join(server_args))
else:
server = Popen(server_args,
stdout = PIPE,
stdin = PIPE,
stderr = PIPE)
outputs = [server.stderr, server.stdout, sys.stdin]
stdin = server.stdin
[...]
while True:
try:
if os.name == 'nt':
outready = [stdout]
else:
outready, inready, exceptready = select.select(outputs, [], [], 1.0)
except:
break
stdout
here is the combined stdout and stderr of the child process that has been started with win32pipe.popen4(...)
The questions arsing are:
- Why not
select()
for the windows version? Does that not work? - If you don't use
select()
there, how can I implement the neccessary timeout thatselect()
provides (which obviously won't work like this here)
Please, help me out!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为你不能在管道上使用 select() 。
在其中一个项目中,我将 Linux 应用程序移植到 Windows,我也错过了这一点,不得不重写整个逻辑。
I think you cannot use select() on pipes.
In one of the projects, where I was porting a linux app to Windows I too had missed this point and had to rewrite the whole logic.