node.js - node.js - 腳本輸出被緩衝到一個消息中,儘管有單獨的echo語句?

91 2

我有一個帶有三個echo語句的shell script :


echo 'first message'



echo 'second message'



echo 'third message'



然後我在node中運行這個腳本,並通過下面的代碼收集輸出:


var child = process.spawn('./test.sh');


child.stdout.on('data', data => {


 data = JSON.stringify(data.toString('utf8'));


 console.log(data);


});



但是奇怪的輸出是 "first messagensecond messagenthird messagen" ,這是一個問題,我期待三種輸出,而不是由於某種形式的緩衝而一起輸出。而且我不能對換行符進行分割,因為單個輸出可能包含換行符。

是否可以區分單個echo語句的消息? (或其他輸出命令,即。 printf,或任何導致將數據寫入stdout或stderror的內容,

編輯:我已經嘗試了unbuffer和stdbuf,這兩種方法都不適用,因為簡單的測試可以驗證它不行,下面是stdbuf嘗試的一個例子,我嘗試了各種不同的參數值,本質上是所有可能的選項。


 var child = process.spawn('stdbuf', ['-i0', '-o0', '-e0', './test.sh']);



為了清楚起見,當我從node運行python腳本時,這個問題也會發生,只有三個簡單的print語句,所以,它是語言無關的,它不是關於bash腳本的,它是關於在基於unix的系統上以任何語言成功檢測腳本的各個輸出。歡迎使用任何能工作的解決方案。

时间: 原作者:

62 0

我從代碼中看到的問題是數據正在被緩衝,並在流中完全讀取。

你可能使用stdbuf修改stdout操作緩衝,並使它與程序的bash輸出一樣緩衝。


const child = process.spawn("stdbuf", ["-oL","./test.sh"]);


child.stdout.on("data", data => {


 data = JSON.stringify(data.toString("utf8"));


 console.log(data);


});



原作者:
58 3

你可以使用作為node API一部分提供的readline介面,更多信息https://nodejs.org/api/readline.html#readline_event_line,你將使用spawn,然後將stdout傳遞給readline,以便它能夠解析行,我不確定這是不是你想要做的,下面是一些示例代碼:


var process = require('child_process');


const readline = require('readline');



var child = process.spawn('./test.sh');



// Use readline interface


const readlinebyline = readline.createInterface({ input: child.stdout });



// Called when a line is received


readlinebyline.on('line', (line) => {


 line = JSON.stringify(line.toString('utf8'));


 console.log(line);


});



輸出:


"first message"


"second message"


"third message"



原作者:
116 2

不要使用console.log


const process_module = require('child_process');



var child = process_module.spawn('./test.sh');


child.stdout.on('data', data => {


 process.stdout.write(data);


});



更新(僅顯示process模塊和process全局對象之間的差異):


const process = require('child_process');



var child = process.spawn(`./test.sh`);


child.stdout.on('data', data => {


 global.process.stdout.write(data); // notice global object


});



我用來測試此腳本的文件是:

python:


#!/usr/bin/env python



print("first message")


print("second message")


print("third message")



bash:


#!/usr/bin/env bash



echo 'first message'


echo 'second message'


echo 'third message'



輸出:


first message


second message


third message



確保它們是可執行的腳本:


chmod a+x test.sh


chmod a+x test.py



原作者:
146 2

基於bash和python的C庫是一個每行緩衝的標準,stdbuf和unbuffer會處理這個問題,但是,這不是操作系統所做的緩衝。

例如,Linux將4096位元組分配給node.js進程與bash進程之間的管道緩衝區。

事實上,管道(node.js )端部的進程沒有嚴格的方法可以看到在另一端寫入(echo的調用),這不是正確的設計(您可以通過單個文件而不是stdout進行通信)。

我在Linux上測試過了:


$ cat test.sh 


echo 'first message'


sleep 0.1


echo 'second message'


sleep 0.1


echo 'third message'


$ cat test.js 


const child_process = require('child_process');


var child = child_process.spawn(`./test.sh`);


child.stdout.on('data', data => {


 data = JSON.stringify(data.toString('utf8'));


 global.process.stdout.write(data); // notice global object


});


$ node test.js


"first messagen""second messagen""third messagen"



原作者:
...