Скрипт NodeJs с порождением child_process в Windows, зачем мне нужно «shell: true» для ошибки ENOENT?

Я использую этот код:

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'});

Это правильно?


person Community    schedule 08.07.2017    source источник


Ответы (1)


При вызове самого spawn в spawn нет команды npm. Таким образом, вы получили это сообщение об ошибке. Вместо использования самого spawn при добавлении shell: true spawn будет использовать оболочку вашей системы для запуска этой команды. Поскольку в вашей системе есть npm, она работает.

let info = spawn('npm', ["-v"], {shell: true, stdio: 'inherit'}); Это правильно?

Код в порядке, если ваши параметры спавна контролируются. Но в целом я предлагаю использовать чистый спавн без использования шелла. Риск уменьшится без непосредственного прикосновения к оболочке.


Так как вам нужен возврат потока из spawn. Я проверил другое решение здесь . Without 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);
}
person Kir Chou    schedule 08.07.2017
comment
Да, конечно, но мне нужен stdout live не в конце моих команд. Как с exec? - person ; 08.07.2017
comment
Я понял вашу причину использования spawn, вы пробовали cwd в качестве параметра? Я обновил код. Пожалуйста, попробуйте. - person Kir Chou; 08.07.2017
comment
Не работает на windows cwd. Я пробовал каждый режим пути: абсолютный, относительный, косая черта назад и вперед. Ничего. - person ; 08.07.2017