Nodejs子进程在记录输出时不等待完成

时间:2018-03-19 14:57:30

标签: javascript python node.js subprocess virtualenv

我正在尝试使用nodejs进程来启动python脚本。 - 这个python脚本在忙碌时记录 - 因为它记录我希望在nodejs进程使用的控制台窗口中显示它。

python脚本非常简单

    ID  Time_x  Time_y
0   a   1:10    1:11
1   a   1:12    1:13
2   b   1:13    NaN
3   c   1:14    1:15
4   d   1:15    NaN

打印'小文本测试',睡眠10秒钟(!),然后引发一个未被捕获的异常,从而完成脚本。

在节点中,我尝试使用它:

from time import sleep
if __name__ == '__main__':
    print('small text testing')
    sleep(10)
    raise Exception('test')

然而,这个“失败”的意思是它只会在python进程运行完毕后打印出来。

现在我知道可以通过 const { exec } = require('child_process'); const exec_str = '. BackgroundServer/BackgroundServer/bin/activate && python BackgroundServer/main.py 1'; const child = exec(exec_str, { // detachment and ignored stdin are the key here: detached: true, stdio: [ 'ignore', 1, 2 ] }); child.unref(); child.stdout.on('data', function(data) { console.log(data.toString()); }); child.stderr.on('data', function(data) { console.error(data.toString()); }); 运行脚本,但这需要我创建一个临时脚本,授予该脚本权限,然后执行该脚本。也不是最佳的。

1 个答案:

答案 0 :(得分:0)

对javascript或node.js了解不多我很确定你的问题是因为如果它作为子进程运行,Python会缓冲它的输出。

要解决此问题,您可以手动确保Python通过添加对sys.stdout.flush()的调用来刷新缓冲区

import sys
from time import sleep
if __name__ == '__main__':
    print('small text testing')
    sys.stdout.flush()
    sleep(10)
    raise Exception('test')

或者你可以通过使用-u参数调用intrepreter来强制Python不作为子进程使用,从而将exec_str修改为

const exec_str = '. BackgroundServer/BackgroundServer/bin/activate && \ 
python -u BackgroundServer/main.py 1';

第一个解决方案将始终刷新输出,如果需要,您可以在其他地方使用它,而无需考虑-u选项。但是,我仍然会推荐第二种方法,因为它仍然允许代码运行缓冲(有时可能是你想要的),而且当使用更长的脚本时,你可能需要插入大量的手动sys.stdout.flush()调用否则。

另外,作为旁注,不需要在Python脚本中引发异常。无论如何,当它到达最后一行时它将结束。