node中子進程同步輸出


管道

通過“child_process”模塊fork出來的子進程都是返回一個ChildProcess對象實例,ChildProcess類比較特殊無法手動創建該對象實例,只能使用fork或者spawn,而且與process對象不同的是,ChildProcess實例的stdin為可寫流,stdout和stderr為可讀流。因此通過childprocess.stdin可以輸入數據,通過childprocess.stdout可將子進程的數據數據輸出到父進程中。

具體實現
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。

具體實現
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;
  }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM