2017-06-03 68 views
1

我有兩個腳本A.js和B.js,以及第三方應用程序(這是開源的)。腳本A.js使用execSync啓動第三方應用程序。腳本B.js使用spawn啓動腳本A.js。不能管,從產卵標準輸出爲特定應用程序

如果我運行本身腳本A.js,我可以看到第三方應用程序的整個輸出。當我通過運行腳本B.js間接運行它時,我只能看到一些輸出。

A.js

const { execSync } = require('child_process'); 
console.log("Hello"); 
execSync('mybinary.exe -arg1 -arg2', { stdio: 'inherit' }); 

B.js

const { spawn } = require('child_process'); 
const app = spawn(process.execPath, ['A.js'], { 
    stdio: ['inherit', null, 'inherit'] 
}); 

app.stdout.on('data', (chunk) => { 
    process.stdout.write(chunk); 
}); 

當我啓動B,我只看到 「Hello」,然而二進制運行(這是一個服務器,我可以打開一個TCP連接到它)。我只是沒有看到輸出。當我自己啓動A時,我看到「Hello」和普通二進制輸出。

如果我改變B的標準輸出,以「繼承」,它的工作原理。

這究竟是爲什麼,以及如何解決這一問題?

更新:似乎與使用兩個腳本沒有任何關係。在不使用stdio繼承的情況下直接生成二進制文件會出現同樣的問題。似乎依賴於第三方應用程序。 如果程序只是打印到stdout,程序如何影響節點?

上下文:我想啓動服務器,然後在服務器準備就緒時運行命令。準備就緒後,服務器將打印出特定的消息。這個想法是等待這條消息被打印出來。打印出此消息後,它不會打印出任何其他內容,但它仍在運行。

我試圖管的具體可執行文件是一個ChatScript server

UPDATE:在這一點上,我認爲它是與我試圖管道的特定二進制文件的東西。我想了解二進制文件如何影響這種行爲,即使用繼承而不是管道。 如果有人能重新與節點腳本(或C++程序),將回答這個問題。


環境

  • 操作系統:Windows 10
  • 控制檯:Cygwin的(並且也嘗試定期命令提示符)。
  • 節點V7.10.0

注意,這是因爲這裏的同一個問題:node.js child_process.spawn no stdout unless 'inherit'

回答

1

的寫道,chatscript正在做的「fprintf中(標準輸出,...)」這是一個緩衝輸出,並保存,直到像(4K?)被緩衝,然後沖洗。例如,在ChatScript/src/os.cpp行1849中的fprintf(stdout)之後添加'fflush(stdout)',然後輸出將工作(有些時候,需要進一步的更改,但我至少在cs_init中獲得了'。 txt'錯誤日誌記錄現在

另一個測試是將chatscript.exe重定向到一個文件並查看該文件得到的內容'chatscript> zz'然後用ctrl-c結束chatscript你會看到zz是空白的還有...這表示IO已經被緩衝並且沒有被適當地輸出。

M:\javascript\test_exec>node b.js 
Hello 

    in cs_init.txt at 0: 
    A subdirectory or file USERS already exists. 
Error opening utf8writeappend file LOGS/startlog.txt: No such file or  directory 
ChatScript Release Version 7.5 pid: 0 32 bit Windows compiled Jun 24 2017 09:42:13 host=local 
Params: dict:2097151 fact:800000 text:100000kb hash:215127 
      buffer:80x80kb cache:1x5000kb userfacts:100 outputlimit:80000  loglimit:80000 
Unable to read dictionarySystem.h 
Missing 37 word files 
read 0 raw words 

    in facts.txt at 0: 
    A subdirectory or file USERS already exists. 
+0

我有一種感覺就是這個問題。你知道爲什麼直接運行chatscript(節點外)爲什麼直接打印標準輸出?是否設置某種標誌來禁用(或降低)緩衝?你會看到它在一個簡單的windows cmd中可以在節點外打印。 – noahnu

0

有這個一個簡單而安全的解決方法是將管道從應用程序輸出到一個文件,然後之後再從同一個文件中讀取,因此,如果事件在嘗試聆聽之前或之後觸發,則不必擔心。

管到文件:

var fs = require('fs'); 
var spawn = require('child_process').spawn; 
var out = fs.openSync('./out.log', 'a'); 
var err = fs.openSync('./err.log', 'a'); 

var child = spawn('applicaiton', [], { 
    detached: true, 
    stdio: [ 'ignore', out, err ] 
}); 

希望它能幫助,我更新它如何去;

祝你好運,

+0

沒有工作當detached爲真(用'shell:true'和'shell:false'測試) )沒有輸出寫入文件,當detached爲false時,只寫入部分輸出,就像當我在我或者管道中輸入一樣原始問題。作爲一個側面說明,當detached爲true(並且shell爲true)並且沒有輸出到文件時,我可以在屏幕上出現的新分離外殼中看到正確的輸出。我無法捕捉那個輸出。 – noahnu

相關問題