2

版本:v8.10.0 平台:Darwin Tapaswenis-MBP 16.7.0 Darwin Kernel Version 16.7.0:; 根:xnu-3789.73.8~1/RELEASE_X86_64 x86_64

我正在尝试将字符串添加到子子进程标准输出。我希望此代码能够在不编辑主进程的现有测试用例的情况下工作。

const child = async (command, options, logger) =>
 new Promise((resolve, reject) => {
   const start = Date.now();

   const child = child_process
  .spawn(command, options)
  .on('error', (err) => reject(err))
  .on('exit', (code, signal) => {
    const duration = Date.now() - start;
    resolve({ code, signal, duration });
  });

child.stdin.write('[some_string]');
child.stdout.pipe(logger.stream());
child.stderr.pipe(logger.stream());
});

我从尝试开始child.stdout.writechild.stdout.write('some_string') 我能够在子子进程输出中记录 some_string,我的测试失败并出现以下错误

events.js:183 抛出错误;// 未处理的“错误”事件 ^ 错误:在 WriteWrap.afterWrite [as oncomplete] (net.js:864:14) 的 _errnoException (util.js:992:11) 处写入 EPIPE

现在要找出它失败的原因,我检查了它是否EPIPE已关闭以写入类似的东西。

process.stdout.on('error', function( err ) {
if (err.code == "EPIPE") {
    process.exit(0);
}
});

child.stdout然后我记录了原来的属性writable is false。与stderr.write子子进程相同。写入子子进程的另一个选项是使用child.stdin,我记录了它的属性,但它给出了null。很好,但我能够用它记录字符串。

child.stdout属性,我可以管道但不能写为writable假的?我在这里没有找到任何有关此的信息。

 Socket {
  connecting: false,
  _hadError: false,
  _handle: 
   Pipe {
     writeQueueSize: 0,
     owner: [Circular],
     onread: [Function: onread],
     reading: true },
  _parent: null,
  _host: null,
  _readableState: 
   ReadableState {
     objectMode: false,
     highWaterMark: 16384,
     buffer: BufferList { head: null, tail: null, length: 0 },
     length: 0,
     pipes: null,
     pipesCount: 0,
     flowing: null,
     ended: false,
     endEmitted: false,
     reading: true,
     sync: false,
     needReadable: true,
     emittedReadable: false,
     readableListening: false,
     resumeScheduled: false,
     destroyed: false,
     defaultEncoding: 'utf8',
     awaitDrain: 0,
     readingMore: false,
     decoder: null,
     encoding: null },
  readable: true,
  domain: null,
  _events: 
   { end: { [Function: bound onceWrapper] listener: [Function: onend] },
     finish: [Function: onSocketFinish],
     _socketEnd: [Function: onSocketEnd],
     close: [Function] },
  _eventsCount: 4,
  _maxListeners: undefined,
  _writableState: 
   WritableState {
     objectMode: false,
     highWaterMark: 16384,
     finalCalled: false,
     needDrain: false,
     ending: false,
     ended: false,
     finished: false,
     destroyed: false,
     decodeStrings: false,
     defaultEncoding: 'utf8',
     length: 0,
     writing: false,
     corked: 0,
     sync: false,
     bufferProcessing: false,
     onwrite: [Function: bound onwrite],
     writecb: null,
     writelen: 0,
     bufferedRequest: null,
     lastBufferedRequest: null,
     pendingcb: 1,
     prefinished: false,
     errorEmitted: false,
     bufferedRequestCount: 0,
     corkedRequestsFree: 
      { next: null,
        entry: null,
        finish: [Function: bound onCorkedFinish] } },
  writable: false,
  allowHalfOpen: false,
  _bytesDispatched: 8,
  _sockname: null,
  _pendingData: null,
  _pendingEncoding: '',
  server: null,
  _server: null,
  [Symbol(asyncId)]: 34495,
  [Symbol(bytesRead)]: 0 }

现在,在添加 child.stdin 之后,在我对主进程的测试中,我做了类似的事情

 const env = process.env;                                                         
 process.env = { fake: 'environment' };                                           

 sinon.spy(child_process, 'spawn');                                               
 sinon.spy(process.stdout, 'write');                                              

try {                                                                            
  await main_process.waitFor();                                                        
} catch (err) {                                                                  
  assert.ifError(err, 'failed');                                                 
}                                                                                

const process_data = process.stdout.write.args[0][0];                                    
process.stdout.write.restore();                                               

assert.equal(                                                                 
  process_data,                                                                       
  '[Fri, 09 Feb 2018 21:57:55 GMT] [another_string] [895ab607-3767-4bbb-bd45- 
 2a3b341cbc46] something\n',
  'abcd'                                                    
);                                                                            

process_data是我得到的主要流程数据(基本上在添加之前.stdin能够获取主要流程记录的数据。现在由于某种原因这已经变得未定义。基本上当我记录的属性时process.stdout.write,args 是空白的,所以它没有获取 args .

为什么在子子进程上写入.stdin会影响process.stdout.write主进程的参数?我在这里想念什么?如果我在这里遗漏了什么,将不胜感激任何指针甚至链接。

我正在做的这个项目是开源的,如果有帮助的话可以分享整个代码。

4

0 回答 0