无法通过管道为特定应用程序生成来自 spawn 的标准输出
Cannot pipe stdout from spawn for a specific application
我有两个脚本 A.js 和 B.js,以及一个第三方应用程序(开源)。脚本 A.js 使用 execSync
启动第 3 方应用程序。脚本 B.js 使用 spawn
.
启动脚本 A.js
如果我 运行 自己编写 A.js 脚本,我可以看到第 3 方应用程序的全部输出。当我通过 运行ning 脚本 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",但是二进制 是 运行ning(它是一个服务器,我可以打开一个 TCP 连接到它)。我只是没有看到输出。当我单独启动 A 时,我看到 "Hello" 和常规二进制文件的输出。
如果我将 B 的标准输出更改为 'inherit',它会起作用。
为什么会发生这种情况,我该如何解决?
更新: 似乎与使用两个脚本没有任何关系。在不使用 stdio inherit 的情况下直接生成二进制文件会出现相同的问题。似乎依赖于第三方应用程序。 如果程序只是打印到标准输出,它会如何影响节点?
CONTEXT: 我想启动服务器,然后在服务器准备就绪时 运行 命令。准备就绪后,服务器会打印出一条特定的消息。这个想法是等待这条消息被打印出来。打印出此消息后,它不会打印出任何其他内容,而是保持 运行ning.
我尝试传输的特定可执行文件是 ChatScript server.
UPDATE:在这一点上,我假设它与我试图通过管道传输的特定二进制文件有关。我想了解二进制文件如何影响这种行为,即使用继承而不是管道。 如果有人可以用节点脚本(或 c 程序)重新创建此行为,那将回答问题。
环境
- OS: Windows 10
- 控制台:Cygwin(也尝试过常规命令提示符)。
- 节点 v7.10.0
请注意,这是与此处相同的问题:node.js child_process.spawn no stdout unless 'inherit'
有一个简单而安全的解决方法是将应用程序的输出通过管道传输到一个文件,然后再从同一个文件中读取它,这样您就不必担心事件是在之前还是之后触发的你试着听了。
管道到文件:
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 ]
});
希望对您有所帮助,请告诉我进展情况;
祝你好运,
chatscript 正在执行的写入操作是 'fprintf( stdout, ...)' 这是一个缓冲输出,会一直保存到(4k?)被缓冲然后刷新。例如,在 ChatScript/src/os.cpp 行 1849 中的 fprintf( stdout ) 之后添加 'fflush(stdout)'... 然后输出工作(有点,需要进一步的更改,但我确实得到了至少 'in cs_init.txt'现在记录错误。
另一个测试只是将 chatscript.exe 重定向到一个文件并查看该文件得到了什么。 'chatscript > zz' 然后用 ctrl-c 结束聊天脚本,您会看到 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.
我有两个脚本 A.js 和 B.js,以及一个第三方应用程序(开源)。脚本 A.js 使用 execSync
启动第 3 方应用程序。脚本 B.js 使用 spawn
.
如果我 运行 自己编写 A.js 脚本,我可以看到第 3 方应用程序的全部输出。当我通过 运行ning 脚本 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",但是二进制 是 运行ning(它是一个服务器,我可以打开一个 TCP 连接到它)。我只是没有看到输出。当我单独启动 A 时,我看到 "Hello" 和常规二进制文件的输出。
如果我将 B 的标准输出更改为 'inherit',它会起作用。
为什么会发生这种情况,我该如何解决?
更新: 似乎与使用两个脚本没有任何关系。在不使用 stdio inherit 的情况下直接生成二进制文件会出现相同的问题。似乎依赖于第三方应用程序。 如果程序只是打印到标准输出,它会如何影响节点?
CONTEXT: 我想启动服务器,然后在服务器准备就绪时 运行 命令。准备就绪后,服务器会打印出一条特定的消息。这个想法是等待这条消息被打印出来。打印出此消息后,它不会打印出任何其他内容,而是保持 运行ning.
我尝试传输的特定可执行文件是 ChatScript server.
UPDATE:在这一点上,我假设它与我试图通过管道传输的特定二进制文件有关。我想了解二进制文件如何影响这种行为,即使用继承而不是管道。 如果有人可以用节点脚本(或 c 程序)重新创建此行为,那将回答问题。
环境
- OS: Windows 10
- 控制台:Cygwin(也尝试过常规命令提示符)。
- 节点 v7.10.0
请注意,这是与此处相同的问题:node.js child_process.spawn no stdout unless 'inherit'
有一个简单而安全的解决方法是将应用程序的输出通过管道传输到一个文件,然后再从同一个文件中读取它,这样您就不必担心事件是在之前还是之后触发的你试着听了。
管道到文件:
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 ]
});
希望对您有所帮助,请告诉我进展情况;
祝你好运,
chatscript 正在执行的写入操作是 'fprintf( stdout, ...)' 这是一个缓冲输出,会一直保存到(4k?)被缓冲然后刷新。例如,在 ChatScript/src/os.cpp 行 1849 中的 fprintf( stdout ) 之后添加 'fflush(stdout)'... 然后输出工作(有点,需要进一步的更改,但我确实得到了至少 'in cs_init.txt'现在记录错误。
另一个测试只是将 chatscript.exe 重定向到一个文件并查看该文件得到了什么。 'chatscript > zz' 然后用 ctrl-c 结束聊天脚本,您会看到 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.