管道
通過“child_process”模組fork出來的子程式都是返回一個ChildProcess物件例項,ChildProcess類比較特殊無法手動建立該物件例項,只能使用fork或者spawn,而且與process物件不同的是,ChildProcess例項的stdin為可寫流,stdout和stderr為可讀流。因此通過childprocess.stdin可以輸入資料,通過childprocess.stdout可將子程式的資料資料輸出到父程式中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
具體實現 var child = require('child_process') , fs = require('fs'); var childProcess = child.exec(cmd, {env: process.env, maxBuffer: 20*1024*1024}, function(err) { }); var stdoutStream = fs.createWriteStream(escape(stdoutFilePath)); childProcess.stdout.pipe(stdoutStream, {end: false}); childProcess.stderr.pipe(stdoutStream, {end: false}); // 使用node的後壓機制 childProcess.stdout.pipe(process.stdout); childProcess.stderr.pipe(process.stderr); var stdoutEnded = false, stderrEnded = false; function tryClosing(){ if(stdoutEnded && stderrEnded){ stdoutStream.end(); } } childProcess.stdout.on('end', function(){ stdoutEnded = true; tryClosing(); }); childProcess.stderr.on('end', function(){ stderrEnded = true; tryClosing(); }); |
這種方式適用於大多數場景,直接使用流特性完成子程式資料的輸出。
檔案檢測
在某些系統的node環境下,“child_process”並未提供execSync特性,因此需要hack,這裡參考shelljs的實現機制。
使用系統相容較好的exec函式完成基本功能,在shell命令執行完畢後寫入狀態資訊到某些臨時檔案,最後通過迴圈不斷讀取新寫入該臨時檔案的資料。由於在shell命令執行過程中需要模擬同步效果,因此在迴圈中不僅僅獲取新寫入的資料,同時需要模擬I/O阻塞操作,此處shelljs的作者通過嘗試所有的同步IO API,發現fs.writeFileSync操作可以較少的減輕CPU利用率,因此使用該函式阻塞I/O。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
具體實現 var child = require('child_process') , fs = require('fs'); var childProcess = child.exec('"+escape(cmd)+"', {env: process.env, maxBuffer: 20*1024*1024}, function(err) { fs.writeFileSync('"+escape(codeFile)+"', err ? err.code.toString() : '0'); }); var previousStdoutContent = ''; // Echoes stdout changes from running process, if not silent function updateStdout() { if (options.silent || !fs.existsSync(stdoutFile)) return; var stdoutContent = fs.readFileSync(stdoutFile, 'utf8'); // No changes since last time? if (stdoutContent.length <= previousStdoutContent.length) return; process.stdout.write(stdoutContent.substr(previousStdoutContent.length)); previousStdoutContent = stdoutContent; } |
打賞支援我寫出更多好文章,謝謝!
打賞作者
打賞支援我寫出更多好文章,謝謝!