版本: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.write
,child.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
主进程的参数?我在这里想念什么?如果我在这里遗漏了什么,将不胜感激任何指针甚至链接。
我正在做的这个项目是开源的,如果有帮助的话可以分享整个代码。