mirror of
https://github.com/zhigang1992/grunt-bg-shell.git
synced 2026-04-30 04:55:03 +08:00
112 lines
2.2 KiB
CoffeeScript
112 lines
2.2 KiB
CoffeeScript
util = require 'util'
|
|
spawn = require('child_process').spawn
|
|
|
|
|
|
exports.execCmd = (command, options, callback)->
|
|
util._extend(
|
|
encoding: "utf8"
|
|
timeout: 0
|
|
maxBuffer: 200 * 1024
|
|
killSignal: "SIGTERM"
|
|
cwd: null
|
|
env: null
|
|
,
|
|
options
|
|
)
|
|
|
|
unless options.maxBuffer > 0 and isFinite options.maxBuffer
|
|
options.maxBuffer = false
|
|
|
|
|
|
if process.platform is "win32"
|
|
file = "cmd.exe"
|
|
args = ["/s", "/c", "\"" + command + "\""]
|
|
options.windowsVerbatimArguments = true
|
|
else
|
|
file = "/bin/sh"
|
|
args = ["-c", command]
|
|
|
|
|
|
child = spawn(file, args,
|
|
cwd: options.cwd
|
|
env: options.env
|
|
stdio: [process.stdin]
|
|
windowsVerbatimArguments: !!options.windowsVerbatimArguments
|
|
)
|
|
|
|
|
|
stdout = null
|
|
stderr = null
|
|
killed = false
|
|
exited = false
|
|
timeoutId = null
|
|
err = null
|
|
|
|
|
|
exithandler = (code, signal) ->
|
|
return if exited
|
|
exited = true
|
|
|
|
if timeoutId
|
|
clearTimeout timeoutId
|
|
|
|
return unless callback
|
|
if err
|
|
callback err, stdout, stderr
|
|
else if code is 0 and signal is null
|
|
callback null, stdout, stderr
|
|
else
|
|
e = new Error "Command failed: " + (stderr || command)
|
|
e.killed = child.killed or killed
|
|
e.code = code
|
|
e.signal = signal
|
|
callback e, stdout, stderr
|
|
|
|
|
|
errorhandler = (e) ->
|
|
err = e
|
|
child.stdout.destroy()
|
|
child.stderr.destroy()
|
|
exithandler()
|
|
|
|
|
|
kill = ->
|
|
child.stdout.destroy()
|
|
child.stderr.destroy()
|
|
killed = true
|
|
try
|
|
child.kill options.killSignal
|
|
catch e
|
|
err = e
|
|
exithandler()
|
|
|
|
|
|
if options.timeout > 0
|
|
timeoutId = setTimeout kill, options.timeout
|
|
|
|
|
|
child.stdout.setEncoding options.encoding
|
|
child.stderr.setEncoding options.encoding
|
|
|
|
|
|
if options.maxBuffer
|
|
stdout = ''
|
|
stderr = ''
|
|
|
|
child.stdout.addListener "data", (chunk) ->
|
|
stdout += chunk
|
|
if stdout.length > options.maxBuffer
|
|
err = new Error("stdout maxBuffer exceeded.")
|
|
kill()
|
|
|
|
child.stderr.addListener "data", (chunk) ->
|
|
stderr += chunk
|
|
if stderr.length > options.maxBuffer
|
|
err = new Error("stderr maxBuffer exceeded.")
|
|
kill()
|
|
|
|
|
|
child.addListener "close", exithandler
|
|
child.addListener "error", errorhandler
|
|
|
|
child |