繁体   English   中英

spawnSync /bin/sh ENOBUFS

[英]spawnSync /bin/sh ENOBUFS

在执行以下行时,错误“ spawnSync /bin/sh ENOBUFS ”在我的 NodeJs 应用程序中非系统地产生:

child_process.execSync(`cd /tmp/myFolder ; tar -xjf myArchive.tar.bz2`);

存档尺寸为 81.5 MB,带有 NVM 的 NodeJs 版本:12.17.0。

问题是execSync模式在 shell 中执行命令,缓冲区有限 (200 Kb) 用于转发执行输出。 此外,默认的 shell 执行选项是“管道”,这意味着必须将输出转发给父级。

为了让 shell 忽略执行输出,即转发到 /dev/null 输出,从而防止缓冲区填满,您必须使用“忽略”执行选项如下:

child_process.execSync(`cd /tmp/myFolder ; tar -xjf myArchive.tar.bz2`, { stdio: 'ignore' });

在此处此处阅读有关execspawn执行模式的更多信息

如果输出对您很重要,请使用 child_process.spawn。

即使您不需要它,执行输出在调试时也很有帮助。 您始终可以添加一个简单的开关,让您可以选择静音输出。

我尽量不使用 child_process.exec,因为 child_process.spawn 工作得一样好,但没有 exec 的限制。 当然,YMMV 如果您的核心应用程序逻辑处理流数据。 child_process.spawn 将在这里工作的原因是因为它流输出而 child_process.exec 缓冲输出,如果你填满最大缓冲区,那么 child_process.exec 将崩溃。 可以通过 options 参数增加 child_process.exec 的缓冲区大小,但请记住,缓冲区越大,您使用的内存越多,而流通常会将内存使用量保持在最低水平。

这是一个参考实现。 仅供参考,此代码适用于 Node v14。

const child_process = require("child_process");

function spawn(instruction, spawnOpts = {}, silenceOutput = false) {
    return new Promise((resolve, reject) => {
        let errorData = "";

        const [command, ...args] = instruction.split(/\s+/);

        if (process.env.DEBUG_COMMANDS === "true") {
            console.log(`Executing \`${instruction}\``);
            console.log("Command", command, "Args", args);
        }

        const spawnedProcess = child_process.spawn(command, args, spawnOpts);

        let data = "";

        spawnedProcess.on("message", console.log);

        spawnedProcess.stdout.on("data", chunk => {
            if (!silenceOutput) {
                console.log(chunk.toString());
            }

            data += chunk.toString();
        });

        spawnedProcess.stderr.on("data", chunk => {
            errorData += chunk.toString();
        });

        spawnedProcess.on("close", function(code) {
            if (code > 0) {
                return reject(new Error(`${errorData} (Failed Instruction: ${instruction})`));
            }

            resolve(data);
        });

        spawnedProcess.on("error", function(err) {
            reject(err);
        });
    });
}

// example usage
async function run() {
    await spawn("echo hello");
    await spawn("echo hello", {}, true);
    await spawn("echo hello", { cwd: "/" });
}

run();

ENOBUFS 表示进程输出大小超出,因此要修复此覆盖进程标准输出,这里是一个使用 nodejs 的示例:

            let ops={}
            ops.args=['logcat','-t',"'m-d h:min:s.000'"]
            //set output file
            ops.log='tmp/logfile.txt'
            largeout=run('adb.exe',ops) 
             console.log(largeout)

             //+++++++++++++++utils+++++++++++++++++++
            function run(cmd,ops={args:'',log:''}) {
            const{readFileSync,openSync}=require('fs');
            cmd=ops.args?cmd+" "+ops.args:cmd;    
            try{
            //override stdio[stdin,stdout,stderr]
            if(ops.log) {let log=openSync(ops.log,'w');ops.stdio=[null,log,log]}
            let rs= require('child_process').execSync(cmd,ops);
            //nb:ops.log:path file used to fix pipe size max 200k ENOBUFS;
            if(ops.log) rs=readFileSync(ops.log,'utf8'); 
            return !rs?false:rs.toString();
            }catch(e){
            console.log('ags.run err:',e.message);
            return false;
            }
            }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM