Выполнение команды cygwin от NodeJS

Используя модуль Node child_process, я хотел бы выполнять команды через оболочку cygwin. Это то, что я пытаюсь:

var exec = require('child_process').execSync;
exec('mkdir -p a/b/c', {shell : 'c:/cygwin64/bin/bash.exe -c'});
TypeError: invalid data
    at WriteStream.Socket.write (net.js:641:11)
    at execSync (child_process.js:503:20)
    at repl:1:1
    at REPLServer.defaultEval (repl.js:262:27)
    at bound (domain.js:287:14)
    at REPLServer.runBound [as eval] (domain.js:300:12)
    at REPLServer. (repl.js:431:12)
    at emitOne (events.js:82:20)
    at REPLServer.emit (events.js:169:7)
    at REPLServer.Interface._onLine (readline.js:212:10)

Я вижу Node child_process.js добавит ключи /s и /c, независимо от параметра shell bash.exe не знает, что делать с этими аргументами.

Я нашел работу для этой проблемы, но она действительно не идеальна:

exec('c:/cygwin64/bin/bash.exe -c "mkdir -p a/b/c"');

Выполнение вышеуказанного, очевидно, будет работать только в системах Windows, а не в UNIX.

Как я могу выполнять команды в оболочке cygwin из NodeJS?

Ответ 1

Это не полное общее решение, потому что больше нужно выполнить с некоторыми параметрами exec(), но это должно позволить вам писать код, который будет работать с Unix, Windows и cygwin, дифференцируя два.

Это решение предполагает, что Cygwin устанавливается в каталог, имя которого включает строку cygwin.

var child_process = require( 'child_process' )
  , home = process.env.HOME
;

function exec( command, options, next ) {
  if( /cygwin/.test( home ) ) {
    command = home.replace( /(cygwin[0-9]*).*/, "$1" ) + "\\bin\\bash.exe -c '" + command.replace( /\\/g, '/' ).replace( /'/g, "\'" ) + "'";
  }

  child_process.exec( command, options, next );
}

Вы можете альтернативно уклониться от child_process.exec условно при работе под Cygwin:

var child_process = require( 'child_process' )
  , home = process.env.HOME
;

if( /cygwin/.test( home ) ) {
  var child_process_exec = child_process.exec
    , bash = home.replace( /(cygwin[0-9]*).*/, "$1" ) + "\\bin\\bash.exe"
  ;

  child_process.exec = function( command, options, next ) {
    command = bash + " -c '" + command.replace( /\\/g, '/' ).replace( /'/g, "\'" ) + "'";

    child_process_exec( command, options, next )
  }
}