Node.js中spawn與exec的異同比較

前言

衆所周知,Node.js在child_process模塊中提供了spawnexec這兩個方法,用來開啓子進程執行指定程序。這兩個方法雖然目的同樣,可是既然Node.js爲咱們提供了兩個方法,那它們之間必然仍是會有一些不一樣之處,下面讓咱們來分析一下他們的異同。html

首先咱們來看看官方API文檔中對它們的說明:node

child_process.spawn(command[, args][, options])

command String 將要運行的命令。
args Array 字符串參數數組。
options 配置對象:shell

  • cwd String 子進程的當前工做目錄。
  • env Object 環境變量鍵值對。
  • stdio Array|String 子進程的stdio配置。
  • detached Boolean 這個子進程將會變成進程組的領導。
  • uid Number 設置用戶進程的ID。
  • gid Number 設置進程組的ID。

返回值: ChildProcess對象windows

利用給定的命令以及參數執行一個新的進程,若是沒有參數數組,那麼args將默認是一個空數組。api

child_process.exec(command[, options], callback)

command String 將要運行的命令,參數使用空格隔開。
options 配置對象:數組

  • cwd String 子進程的當前工做目錄。
  • env Object 環境變量鍵值對。
  • encoding String 字符編碼(默認: 'utf8')。
  • shell String 將要執行命令的Shell(默認: 在UNIX中爲/bin/sh, 在Windows中爲cmd.exe, Shell應當能識別 -c 開關在UNIX中,或 /s /cWindows中。 在Windows中,命令行解析應當能兼容cmd.exe)。
  • timeout Number 超時時間(默認: 0)。
  • maxBuffer Number 在stdout或stderr中容許存在的最大緩衝(二進制),若是超出那麼子進程將會被殺死 (默認: 200*1024)。
  • killSignal String 結束信號(默認:'SIGTERM')。
  • detached Boolean 這個子進程將會變成進程組的領導。
  • uid Number 設置用戶進程的ID。
  • gid Number 設置進程組的ID。

callback Function 當子進程執行完畢後將會執行的回調函數,參數有:緩存

  • error Error
  • stdout Buffer
  • stderr Buffer

返回值: ChildProcess對象函數

在Shell中運行一個命令,並緩存命令的輸出。ui

異同

從文檔裏能夠得出的一些相同點:

1,它們都用於開一個子進程執行指定命令。編碼

2,它們均可以自定義子進程的運行環境。

3,它們都返回一個ChildProcess對象,因此他們均可以取得子進程的標準輸入流,標準輸出流和標準錯誤流 。

不一樣點:

1,接受參數的方式: spawn使用了參數數組,而exec則直接接在命令後。

2,子進程返回給Node的數據量: spawn沒有限制子進程能夠返回給Node的數據大小,而exec則在options配置對象中有maxBuffer參數限制,且默認爲200K,若是超出,那麼子進程將會被殺死,並報錯:Error:maxBuffer exceeded,雖然能夠手動調大maxBuffer參數,可是並不被推薦。由此可窺見一番Node.js設置這兩個API時的部分本意,spawn應用來運行返回大量數據的子進程,如圖像處理,文件讀取等。而exec則應用來運行只返回少許返回值的子進程,如只返回一個狀態碼。

3,調用對象: 雖然在官方文檔中,兩個方法接受的第一個參數標註的都是command,即要執行的命令,但其實否則。spawn接受的第一個參數爲文件,而exec接受的第一個參數纔是命令。在Node的源碼中關於spawn的部分有以下一段:

jsvar spawn = exports.spawn = function(file, args, options)

而在exec部分則有以下一段:

jsif (process.platform === 'win32') {
file = 'cmd.exe';
args = ['/s', '/c', '"' + command + '"'];
// Make a shallow copy before patching so we don't clobber the user's
// options object.
options = util._extend({}, options);
options.windowsVerbatimArguments = true;
} else {
  file = '/bin/sh';
  args = ['-c', command];
}

因此在Windows下直接運行 require('child_process').spawn('dir') 會報異常說沒有此文件,而使用exec則不會。若必定要使用spwan,則應寫成require('child_process').spawn('cmd.exe',['\s', '\c', 'dir'])

4,回調函數: exec方法相比spawn方法,多提供了一個回調函數,能夠更便捷得獲取子進程輸出。這與爲返回的ChildProcess對象的stdoutstderr監聽data事件來得到輸出的區別在於:data事件的方式,會在子進程一有數據時就觸發,並把數據返回給Node。而回調函數,則會先將數據緩存在內存中(數據量小於maxBuffer參數),等待子進程運行完畢後,再調用回調函數,並把最終數據交給回調函數。

參考

http://www.hacksparrow.com/difference-between-spawn-and-exec-of-node-j...

https://cnodejs.org/topic/507285c101d0b80148f7c538

相關文章
相關標籤/搜索