Использование nodejs spawn вызывает ошибки "unknown option -" и "[Error: spawn ENOENT]"
Я пытаюсь получить spawn
для выполнения rm -rf node_modules
, за которым следует npm install
(в Windows 7; команды nx предоставлены прозрачно установленным CygWin. Все команды nx разрешают на командной строке просто отлично).
Я изначально использовал это с помощью exec
, но хотел поймать информацию stdout/stderr по мере ее возникновения, поэтому я решил использовать spawn
и переписать код для его использования. Однако это все ломает.
Команда rm
, переписанная, стала следующей:
var spawn = require("child_process").spawn,
child = spawn("rm", ["-rf", "node_modules"]);
child.stdout.on('data', function (data) { console.log(data.toString()); });
child.stderr.on('data', function (data) { console.log(data.toString()); });
child.on('error', function() { console.log(arguments); });
Однако при запуске это приводит к следующей ошибке:
rm: unknown option -- ,
Try `rm --help' for more information.
Команда npm
, переписанная, стала следующей:
var spawn = require("child_process").spawn,
child = spawn("npm", ["install"]);
child.stdout.on('data', function (data) { console.log(data.toString()); });
child.stderr.on('data', function (data) { console.log(data.toString()); });
child.on('error', function() { console.log(arguments); });
Однако при запуске это приводит к следующей ошибке:
{
'0': {
[Error: spawn ENOENT]
code: 'ENOENT',
errno: 'ENOENT',
syscall: 'spawn'
}
}
Как заставить spwn запускать те же команды, которые отлично работали с помощью exec
, не вызывая ошибок во всем месте? И почему это не работает? Чтение API, http://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options, похоже, предполагает, что именно так предполагается использовать икру...
Ответы
Ответ 1
После долгих попыток по-разному я наконец-то взглянул на то, что на самом деле означает "npm" в Windows, и оказалось, что это bash-скрипт с именем npm
, а также пакетный скрипт для npm.cmd
называемый npm.cmd
(понятия не имею) почему это .cmd, это должно быть .bat, но там у вас есть). Средство распознавания команд Windows увидит npm
, заметит, что это не исполняемый файл, увидит npm.cmd
, а затем заметит, что это исполняемый файл, и затем будет использовать его вместо этого. Это полезно, когда вы находитесь в терминале, но spawn()
не будет делать такого разрешения: передача его через npm
приведет к сбою, потому что это не исполняемый файл. Передача в качестве команды npm.cmd
, однако, работает отлично.
(Кроме того, не уверен, почему ранее rm
неудачу, так как это на самом деле работает правильно, без каких-либо изменений, которые я могу сказать. Возможно, неправильно воспринял это как часть проблемы, хотя на самом деле это не так.)
Итак: если вы запускаете spawn
надписью ENOENT в окнах, когда команда, которую вы пытаетесь вызвать, работает в простой командной строке, выясните, является ли команда, которую вы вызываете, истинным исполняемым файлом или существует .bat
/.cmd
файл, который вместо вас будет запускать командная строка. Если это так, порождайте это.
редактировать
так как в этом посте по-прежнему поступают ответы, хороший способ убедиться, что команда всегда работает, - это загрузить ее на основе process.platform
, который будет win32
для windows.
var npm = (process.platform === "win32" ? "npm.cmd" : "npm"),
child = spawn(npm, ["install", ...]);
...
Ответ 2
Я думаю, что это может быть какой-то cygwin gotcha. Я запускаю Ubuntu 12.04 и пытался дублировать вашу проблему, но для меня это работает отлично. Короче говоря, я не вижу ничего, что вы делаете неправильно.
Если он жалуется на этот вариант, возможно, разбить его на несколько вариантов:
child = spawn("rm", ["-r", "-f", "node_modules"]);
Такой градиент, но это работает и на моем Ubuntu 12.04. Вы можете попытаться просто удалить один файл и посмотреть, получаете ли вы то же самое.
child = spawn("rm", ["/home/username/Desktop/TestFile"]);
Если это все еще не удается, тогда вы знаете, что работаете против каких-то сумасшедших вещей.
Вы даже можете попытаться просто выполнить команду без таких параметров:
child = spawn("ls");
Если это все еще не удастся, вы вряд ли получите, что икру будет работать вообще, я буду догадываться и буду благодарен, что работает хотя бы exec.
Не так много в области ответов для вас, но, как я уже сказал, я не вижу ничего, что вы делаете неправильно.
Кроме того, я не вижу, как ваша команда npm будет работать, потому что вы не указали, что устанавливать, но, как говорится, она терпит неудачу иначе, чем я вижу, что она не работает здесь, если я использую та же команда., Я вижу много выходных данных stderr, а не общую ошибку.
Кстати, я запускаю node v0.8.21. Вы можете запросить это с помощью node -v. Если вы используете другую версию, возможно, попробуйте выполнить 0.8.21.
Ответ 3
Используйте полный путь для процесса, например:
var cmd = require('child_process').spawn("C:\\windows\\system32\\cmd.exe");