从node.js运行脚本,捕获标准输出,通过networking套接字发送
我正在通过node.js调用通过stdout返回数据的Ruby脚本,我已经设法让节点发送一些数据通过它的networking套接字,但我缺less线条,并不真正了解我什么这样做。 从研究,它看起来像我正在与一个stream,但我不能让我的头大部分文件,因为这是非常新的,在我的头:(
当通过bash shell运行时,我的Ruby脚本输出如下到stdout;
{"element":"SENS02","data":{"type":"SEN","descr":"T100"}} {"element":"SENS01","data":{"type":"SEN","descr":" "}} {"element":"LED1","data":{"type":"LED","state":"1"}} {"element":"LED2","data":{"type":"LED","state":"0"}}
当在控制台上运行时,一切都很好 – 当我通过我的node.js脚本调用它时,我只获得每一行的第二行,例如节点将输出;
{"element":"SENS02","data":{"type":"SEN","descr":"T100"}} {"element":"LED1","data":{"type":"LED","state":"1"}}
我的node.js脚本部分在下面;
var cp = require('child_process'); var tail = cp.spawn('test.rb'); // Get updates from ruby script // tail.stdout.on('data', function(chunk) { var pumper = chunk.toString().slice(0,58); var closer = JSON.parse(pumper); socket.emit('MAP.room1', closer); });
如果有人可以帮忙,我也会偶尔碰到以下错误:
未定义:0
^ SyntaxError:在Object.parseinput的意外结束(native)
我需要能够输出从我的ruby脚本收到的每一行。 任何人的答案请使用我自己的代码,而不是随机的例子,因为它只是试图了解什么是什么和“这对我意味着什么”时,只是混淆了我。 我试过看着.pipe,但所有的例子让我困惑,我不明白如何适应他们为我自己的脚本。 从ruby输出的是一次一个JS对象1行,我需要我的web套接字一次发射完全相同的东西。
完成console.log(chunk.toString())
以获得可读的输出后,它已经减轻了一些奇怪的事情 – 一个额外的换行或什么东西。
控制台的输出是
{"element":"SENS02","data":{"type":"SEN","descr":"T100"}} {"element":"SENS01","data":{"type":"SEN","descr":" "}} {"element":"LED1","data":{"type":"LED","state":"1"}} {"element":"LED2","data":{"type":"LED","state":"0"}}
我怎样才能绕过这个? 这可能会导致我的其他'意外的input结束'错误?
如果我做var pumper = chunk.slice(0,-1); console.log(pumper.toString())
var pumper = chunk.slice(0,-1); console.log(pumper.toString())
然后我得到如上所示的输出奇数/额外/胭脂换行符。 尽pipe如此,我仍然没有进一步向这个输出到networking套接字。
我可以从networking套接字中得到这个,但是它显示我仍然有某种方式?!?!
["{\"element\":\"SENS02\",\"data\":{\"type\":\"SEN\",\"descr\":\"T100\"}}\n{\"element\":\"SENS01\",\"data\":{\"type\":\"SEN\",\"descr\":\" \"}}"]}
我需要那回到单一的平线,就像我在我的控制台…
所以按照下面的build议,我现在通过使用这个代码得到所需的输出。 我仍然得到): Unexpected end of input
在控制台中logging的): Unexpected end of input
,似乎来自我从我的Ruby脚本得到额外的行饲料。 已经运行脚本了几天没有崩溃, 似乎所有的数据正在通过完整parsing到Web套接字。 我仍然需要阅读和充分理解这是为什么,但否则似乎已经解决了我的问题。
tail.stdout.on('data', function(chunk) { var closer = chunk.toString() var sampArray = closer.split('\n'); for (var i = 0; i < sampArray.length; i++) { try { var newObj = JSON.parse(sampArray[i]); socket.emit('MAP.room1', newObj); } catch (err) { console.log('): ' + err.message); } } });
如果您打算为每个数据块使用JSON.parse()
,则需要预先分析换行符上的每个块\n
。
JSON.parse
不能将由换行符分隔的多个对象parsing为同一个string中的 2个不同对象。
这些是单独有效的:
"{\"element\":\"SENS02\",\"data\":{\"type\":\"SEN\",\"descr\":\"T100\"}}" "{\"element\":\"SENS02\",\"data\":{\"type\":\"SEN\",\"descr\":\"T100\"}}\n" "{\"element\":\"SENS02\",\"data\":{\"type\":\"SEN\",\"descr\":\"T100\"}}\r\n"
这不是:
"{\"element\":\"SENS02\",\"data\":{\"type\":\"SEN\",\"descr\":\"T100\"}}\n{\"element\":\"SENS01\",\"data\":{\"type\":\"SEN\",\"descr\":\" \"}}"
如果意图是parsing整个数据结构,那么你需要重新组织ruby脚本的输出到类似于下面的东西。
{ "elements": [ { "name": "SENS02", "data": { "type": "SEN", "descr": "T100" } }, { "name": "SENS01", "data": { "type": "SEN", "descr": " " } }, { "name": "LED1", "data": { "type": "LED", "state": "1" } }, { "name": "LED2", "data": { "type": "LED", "state": "0" } } ] }
你如何parsinginput(粗略的例子)
var sample = "{\"element\":\"SENS02\",\"data\":{\"type\":\"SEN\",\"descr\":\"T100\"}}\n{\"element\":\"SENS01\",\"data\":{\"type\":\"SEN\",\"descr\":\" \"}}\n{\"element\":\"LED1\",\"data\":{\"type\":\"LED\",\"state\":\"1\"}}\n{\"element\":\"LED2\",\"data\":{\"type\":\"LED\",\"state\":\"0\"}}"; var sampArray = sample.split('\n'); for (var i = 0; i < sampArray.length; i++) { try { var newObj = JSON.parse(sampArray[i]); // socket.emit(newObj); } catch (err) { console.log('): ' + err.message); } }
尝试spawn
你的ruby脚本, exec
是缓冲输出,这可能是你所看到的原因。
看到
PS
用一个try-catch
块包装JSON.parse
,并打印失败时失败的数据