一个有child_process的Promise在Node.js中运行Python脚本-进程在所有数据之前退出

问题描述

我正在尝试让sublist3r在节点应用程序中运行。它会运行,但是只显示横幅,然后在大约5秒钟后退出。该脚本应该可以访问网络,大约需要30秒钟才能运行。如果我不使用承诺,它将很好地工作。是否与pyrog.stdout.on('data')输出之前不等待有关?我已经阅读并尝试'end',但没有运气。

如果不涉及编辑python脚本,则尝试this article上的所有内容(我认为我不需要这样做!!)

也请阅读Node.js Child Process,但其中没有提及将承诺与spawn一起使用,我相信这是运行Python脚本所需要的。

sublist3r screen shot

我使用Promises错误吗?

非常感谢您的帮助

编辑:已添加至runPy,已验证相同问题。也尝试将其设置为变量let test = await runPy ...失败

var express = require('express');
var router = express.Router();

let runPy = new Promise((success,nosuccess) => {
    const {spawn} = require('child_process')
    const pyprog = spawn('python',['/path/to/sublist3r.py','-d','domain.com'] )

    pyprog.stdout.on('data',(data) => {
        success(data)
    })

    pyprog.stderr.on('data',(data) => {
        nosuccess(data)
    })

    pyprog.on('close',(code) => {
        console.log(`child process ended with ${code}`);
    })
})


/* GET home page. */
router.get('/',async (req,res) => {

    // EDIT:  Added await and verified same issue.
    await runPy.then(fromrunPy => {
        console.log(fromrunPy.toString());
    })

    // It works fine below,but I want a promise for no other reason that I can't get it to work...
    // const { spawn } = require('child_process');
    // const pyProg = spawn('python',['/home/wayne/BugHunterJS/controllers/Sublist3r/sublist3r.py',req.body.domain]);
    
    // console.log('inside post');
    // pyProg.stdout.on('data',function(data) {
    //     let sublist3rData = data.toString();
    //     console.log(sublist3rData);
    // });

  });

module.exports = router

解决方法

询问后不久,我找到了解决方案,如果有人在找。我仍然不太确定它是如何工作的,以后再弄清楚。我认为将其推入数组是关键。

const {
    spawn
} = require('child_process')
const logOutput = (name) => (data) => console.log(`[${name}] ${data}`)


function run() {
    return new Promise((resolve,reject) => {
        const process = spawn('python',['/path/sublist3r.py','-d','domain.com']);

        const out = []
        process.stdout.on(
            'data',(data) => {
                out.push(data.toString());
                logOutput('stdout')(data);
            }
        );

        const err = []
        process.stderr.on(
            'data',(data) => {
                err.push(data.toString());
                logOutput('stderr')(data);
            }
        );

        process.on('exit',(code,signal) => {
            logOutput('exit')(`${code} (${signal})`)
            if (code === 0) {
                resolve(out);
            } else {
                reject(new Error(err.join('\n')))
            }
        });
    });
}

(async () => {
    try {
        const output = await run()
        logOutput('main')(output)
        process.exit(0)
    } catch (e) {
        console.error('Error during script execution ',e.stack);
        process.exit(1);
    }
})();