簡體   English   中英

Node.js:捕獲`child_process.spawn`的STDOUT

[英]Node.js: Capture STDOUT of `child_process.spawn`

我需要捕獲生成的子進程的自定義輸出。

child_process.spawn(command[, args][, options])

例如,

var s = fs.createWriteStream('/tmp/test.txt');
child_process.spawn('ifconfig', [], {stdio: [null, s, null]})

現在我如何實時讀取/tmp/test.txt

看起來child_process.spawn沒有使用stream.Writable.prototype.write也沒有使用stream.Writable.prototype._write來執行它。

例如,

s.write = function() { console.log("this will never get printed"); };

以及,

s.__proto__._write = function() { console.log("this will never get printed"); };

看起來它使用引擎蓋下的文件描述符從child_process.spawn寫入文件。

這樣做不起作用:

var s2 = fs.createReadStream('/tmp/test.txt');
s2.on("data", function() { console.log("this will never get printed either"); });

那么,我如何獲得子進程的STDOUT內容呢?

我想要實現的是將子進程的STDOUT流式傳輸到套接字。 如果我將socket作為stdio參數直接提供給child_process.spawn ,它會在完成時關閉套接字,但我想保持它打開。

更新:

解決方案是使用默認的{stdio: ['pipe', 'pipe', 'pipe']}選項,並監聽子進程的已創建.stdout

var cmd = child_process.spaw('ifconfig');
cmd.stdout.on("data", (data) => { ... });

現在,提高賭注,一個更具挑戰性的問題:

- 您如何閱讀子進程的STDOUT並仍然保留顏色?

例如,如果您將STDOUT發送到process.stdout如下所示:

child_process.spawn('ifconfig', [], {stdio: [null, process.stdout, null]});

它將保持顏色並將彩色輸出打印到控制台,因為.isTTY屬性在process.stdout上設置為true

process.stdout.isTTY // true

現在,如果您使用默認的{stdio: ['pipe', 'pipe', 'pipe']} ,您將讀取的數據將被剝離控制台顏色。 你怎么得到顏色?

一種方法是使用fs.createWriteStream創建自己的自定義流,因為child_process.spawn要求您的流具有文件描述符。

然后將該流的.isTTY設置為true ,以保留顏色。

最后你需要捕獲child_process.spawn寫入該流的數據,但由於child_process.spawn不使用流的.prototype.write.prototype._write ,你需要在其他hacky中捕獲它的內容方式。

這可能就是為什么child_process.spawn要求你的流有一個文件描述符,因為它繞過.prototype.write調用並直​​接寫入引擎下的文件。

任何想法如何實現這一點?

您可以不使用臨時文件來執行此操作:

var process = child_process.spawn(command[, args][, options]);
process.stdout.on('data', function (chunk) {
    console.log(chunk);
});

嗨,我在打電話,但我會盡力指導你。 如果需要,我會在計算機附近澄清一下

我想你想要的是從一個產生中讀取stdout並對數據做些什么?

您可以為spawn提供變量名稱,而不是僅運行該函數,例如:

var child = spawn();

然后聽輸出如:

child.stdout.on('data', function(data) {
    console.log(data.toString());
});

您可以使用它將數據寫入文件或您可能想要使用的任何內容。

stdio選項需要文件描述符,而不是流對象,所以一種方法是使用fs.openSync()來創建輸出文件描述符和我們。

以你的第一個例子,但使用fs.openSync()

var s = fs.openSync('/tmp/test.txt', 'w');
var p = child_process.spawn('ifconfig', [], {stdio: [process.stdin, s, process.stderr]});

您還可以將stdout和stderr都設置為相同的文件描述符(效果與bash的2>&1 )。

完成后您需要關閉文件,因此:

p.on('close', function(code) {
  fs.closeSync(s);
  // do something useful with the exit code ...
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM