我有两个脚本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' sdout改为'继承',它就有效。
为什么会发生这种情况,我该如何解决这个问题?
更新:似乎与使用两个脚本无关。直接生成二进制文件而不使用stdio继承会出现同样的问题。似乎依赖于第三方应用程序。 如果程序只打印到stdout,程序如何影响节点?
语境:我想启动服务器,然后在服务器准备就绪时运行命令。准备就绪后,服务器会打印出特定的消息。我的想法是等待打印这条消息。打印出此消息后,它不打印任何其他内容,但它仍然在运行。
我试图管道的特定可执行文件是ChatScript server。
更新:此时,我认为它是特定二进制文件的一部分,我试图管道。我想了解二进制文件如何影响这种行为,即使用继承而不是管道。 如果有人可以使用节点脚本(或c程序)重新创建此行为,则会回答问题。
环境
请注意,这与此处的问题相同:node.js child_process.spawn no stdout unless 'inherit'
答案 0 :(得分:1)
chatscript正在执行的写操作是'fprintf(stdout,...)'这是一个缓冲输出,并保存,直到缓冲然后刷新(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.
答案 1 :(得分: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 ]
});
希望它有所帮助,让我了解它的进展情况;
祝你好运,