带有child_process的NodeJs脚本在Windows上生成,为什么我需要&shell; true:'对于ENOENT错误?

时间:2017-07-08 13:36:03

标签: node.js shell cmd child-process spawn

我正在使用此代码:

const {
  spawn
} = require('child_process');

let info = spawn('npm', ["-v"]);

info.on('close', () => {
  console.log('closed');
}

但我有这个错误:

events.js:182
      throw er; // Unhandled 'error' event
      ^

Error: spawn npm ENOENT
    at exports._errnoException (util.js:1022:11)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:189:19)
    at onErrorNT (internal/child_process.js:366:16)
    at _combinedTickCallback (internal/process/next_tick.js:102:11)
    at process._tickCallback (internal/process/next_tick.js:161:9)
    at Function.Module.runMain (module.js:607:11)
    at startup (bootstrap_node.js:158:16)
    at bootstrap_node.js:575:3

如果我改用:

let info = spawn('npm', ["-v"], {shell: true});

它有效!

但为什么我需要shell: true?我还需要看到该产卵的标准输出,所以我也使用它:

let info = spawn('npm', ["-v"], {shell: true, stdio: 'inherit'});

这是对的吗?

1 个答案:

答案 0 :(得分:3)

在调用spawn本身时,spawn下没有npm命令。因此,您收到了该错误消息。在添加shell: true时,spawn将使用系统的 shell 来运行该命令,而不是使用spawn本身。由于您的系统有npm,因此可以使用。

  

let info = spawn('npm', ["-v"], {shell: true, stdio: 'inherit'});这是对的吗?

如果您的spawn参数是可控的,那么代码就可以了。但一般来说,我建议使用纯生成而不使用shell。如果不直接接触外壳,风险就会降低。

因为你需要从spawn返回流。我已经检查了其他解决方案hereWithout shell: true,您可以使用以下代码:

const {
  spawn
} = require('child_process');

let projectPath = ''//the path of your project
let info = spawn('npm', ['-v'], { cwd: projectPath });

let result = '';
info.stdout.on('data', function(data) {  
  result += data.toString();
  console.log(result);
}