【问题标题】:spawnSync /bin/sh ENOBUFSspawnSync /bin/sh ENOBUFS
【发布时间】:2020-12-27 00:00:36
【问题描述】:

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

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

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

【问题讨论】:

    标签: javascript node.js


    【解决方案1】:

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

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

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

    详细了解 execspawn 执行模式 herehere

    【讨论】:

      【解决方案2】:

      如果输出对您很重要,请使用 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();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-01-30
        • 2022-08-19
        • 2010-09-14
        • 2019-07-24
        • 1970-01-01
        • 2011-04-28
        相关资源
        最近更新 更多