如何使用可读的非阻塞输出管道在linux上用python启动node.js子进程
我试图在python中创建node.js的子进程,以执行javascript代码并读取输出 这段代码在Windows10中运行,但在Ubuntu Linux上它给出了一个错误。当节点启动时,它会在stdout上给出一个提示如何使用可读的非阻塞输出管道在linux上用python启动node.js子进程,python,node.js,linux,subprocess,nonblocking,Python,Node.js,Linux,Subprocess,Nonblocking,我试图在python中创建node.js的子进程,以执行javascript代码并读取输出 这段代码在Windows10中运行,但在Ubuntu Linux上它给出了一个错误。当节点启动时,它会在stdout上给出一个提示,此代码尝试读取该提示,以验证节点已启动,并且管道可读,但在Linux上无法正常工作 import os import subprocess import time import re import json import logging logger = logging.g
,此代码尝试读取该提示,以验证节点已启动,并且管道可读,但在Linux上无法正常工作
import os
import subprocess
import time
import re
import json
import logging
logger = logging.getLogger(__name__)
if "nt" == os.name:
import msvcrt
from ctypes import windll, byref, wintypes, GetLastError, WinError
from ctypes.wintypes import HANDLE, DWORD, BOOL, LPDWORD
PIPE_NOWAIT = wintypes.DWORD(0x00000001)
ERROR_NO_DATA = 232
else:
import fcntl
class NodeEngine:
def __init__(self):
self.stdout_fd = None
self.p_stdout_fd = None
self.stdout = None
self.proc = None
self.__init_pipes()
def __init_pipes(self):
self.stdout_fd, self.p_stdout_fd = os.pipe()
self.pipe_no_wait(self.stdout_fd)
self.stdout = os.fdopen(self.p_stdout_fd,"w")
def pipe_no_wait(self, pipefd):
if "nt" == os.name:
SetNamedPipeHandleState = windll.kernel32.SetNamedPipeHandleState
SetNamedPipeHandleState.argtypes = [HANDLE, LPDWORD, LPDWORD, LPDWORD]
SetNamedPipeHandleState.restype = BOOL
h = msvcrt.get_osfhandle(pipefd)
res = windll.kernel32.SetNamedPipeHandleState(h, byref(PIPE_NOWAIT), None, None)
if res == 0:
print(WinError())
return False
return True
else:
fl = fcntl.fcntl(pipefd, fcntl.F_GETFL)
fcntl.fcntl(pipefd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
def start(self):
self.proc = subprocess.Popen(
["node","-i"],
stdin=subprocess.PIPE,
stdout=self.stdout,
# stderr=subprocess.PIPE,
shell=True
)
bytes_read = 0
ret = ""
timeout = time.time() + 10
while 0 == bytes_read or 1024 == bytes_read:
try:
data = os.read(self.stdout_fd,1024)
ret = ret + data.decode("utf-8")
bytes_read = len(data)
except Exception as e:
if time.time() >= timeout:
raise e
self.stdout.flush()
bytes_read = 0
def close(self):
try:
self.proc.stdin.close()
except:
pass
self.proc.terminate()
self.proc.wait(timeout=0.2)
if __name__ == '__main__':
engine = NodeEngine()
engine.start()
“刷新”命令似乎不起作用。有没有办法让它在Linux和Windows上正常工作?我发现了这个bug,它非常微妙。当使用shell=True的Popen时,第一个参数不应该是列表 我变了
self.proc = subprocess.Popen(
["node","-i"],
stdin=subprocess.PIPE,
stdout=self.stdout,
# stderr=subprocess.PIPE,
shell=True
)
到
现在它可以在Linux和Windows上运行
注意:我将保留此问题,以便找到更好的解决方案好的解决方案,拉尔夫!
self.proc = subprocess.Popen(
"node -i",
stdin=subprocess.PIPE,
stdout=self.stdout,
# stderr=subprocess.PIPE,
shell=True
)