如何将 stdout 从一个子进程传递到 nodejs 中的另一个子进程?
How can I pass stdout from one child process to another child process in nodejs?
当我尝试将 stdout 从一个进程传递到另一个进程的 stdin 时,我遇到了一个神秘错误。
// test.js
const child_process = require("child_process");
const proc = child_process.spawn("ls", ["-a"]);
const res = child_process.spawnSync("head", ["-n", "3"], {
stdio: [proc.stdout, "pipe", "pipe"],
});
console.log(res.toString("utf8"));
当我 运行 node test.js
使用节点版本 v16.13.1
时,我没有看到 ls -a | head -n 3
的结果,而是收到以下错误:
node test.js[12920]: c:\ws\src\spawn_sync.cc:932: Assertion `0 && "invalid child stdio type"' failed.
1: 00007FF63F1230AF v8::internal::CodeObjectRegistry::~CodeObjectRegistry+112511
2: 00007FF63F0B2216 DSA_meth_get_flags+65542
3: 00007FF63F0B25D1 DSA_meth_get_flags+66497
4: 00007FF63EFD2C69 v8::internal::wasm::WasmCode::code_comments_offset+35065
...
34: 00007FF63FF63A88 v8::internal::compiler::RepresentationChanger::Uint32OverflowOperatorFor+14472
35: 00007FFE6C787034 BaseThreadInitThunk+20
36: 00007FFE6E642651 RtlUserThreadStart+33
我不能混合使用 child_process.spawn
和 child_process.spawn_sync
吗?
如果我将 child_process.spawn_sync
更改为 child_process.spawn
,这会起作用,但我需要命令调用是同步的。
不,你不能混合使用它们,选择一个:同步(都spawnSync
)或异步(你可以通过async/await
同步执行):
// all sync
const proc = child_process.spawnSync('ls', ['-a']);
const res = child_process.spawnSync('head', ['-n', '3'], {input: proc.stdout });
console.log('sync: res', res.stdout.toString('utf8'));
// all async, await result
const cp = () => {
return new Promise((resolve, reject) => {
const proc = child_process.spawn('ls', ['-a']);
const res = child_process.spawn('head', ['-n', '3']);
// pipe between processes
proc.stdout.pipe(res.stdin);
const buffers = [];
res.stdout.on('data', (chunk) => buffers.push(chunk));
res.stderr.on('data', (data) => {
console.error(`stderr: ${data.toString()}`);
reject(data.toString())
});
res.stdout.on('end', () => {
const result = (Buffer.concat(buffers)).toString();
console.log(`done, result:\n${result}`);
resolve(result);
});
});
};
// get results synchronously
(async() => {
console.log('await res:', await cp());
})();
当我尝试将 stdout 从一个进程传递到另一个进程的 stdin 时,我遇到了一个神秘错误。
// test.js
const child_process = require("child_process");
const proc = child_process.spawn("ls", ["-a"]);
const res = child_process.spawnSync("head", ["-n", "3"], {
stdio: [proc.stdout, "pipe", "pipe"],
});
console.log(res.toString("utf8"));
当我 运行 node test.js
使用节点版本 v16.13.1
时,我没有看到 ls -a | head -n 3
的结果,而是收到以下错误:
node test.js[12920]: c:\ws\src\spawn_sync.cc:932: Assertion `0 && "invalid child stdio type"' failed.
1: 00007FF63F1230AF v8::internal::CodeObjectRegistry::~CodeObjectRegistry+112511
2: 00007FF63F0B2216 DSA_meth_get_flags+65542
3: 00007FF63F0B25D1 DSA_meth_get_flags+66497
4: 00007FF63EFD2C69 v8::internal::wasm::WasmCode::code_comments_offset+35065
...
34: 00007FF63FF63A88 v8::internal::compiler::RepresentationChanger::Uint32OverflowOperatorFor+14472
35: 00007FFE6C787034 BaseThreadInitThunk+20
36: 00007FFE6E642651 RtlUserThreadStart+33
我不能混合使用 child_process.spawn
和 child_process.spawn_sync
吗?
如果我将 child_process.spawn_sync
更改为 child_process.spawn
,这会起作用,但我需要命令调用是同步的。
不,你不能混合使用它们,选择一个:同步(都spawnSync
)或异步(你可以通过async/await
同步执行):
// all sync
const proc = child_process.spawnSync('ls', ['-a']);
const res = child_process.spawnSync('head', ['-n', '3'], {input: proc.stdout });
console.log('sync: res', res.stdout.toString('utf8'));
// all async, await result
const cp = () => {
return new Promise((resolve, reject) => {
const proc = child_process.spawn('ls', ['-a']);
const res = child_process.spawn('head', ['-n', '3']);
// pipe between processes
proc.stdout.pipe(res.stdin);
const buffers = [];
res.stdout.on('data', (chunk) => buffers.push(chunk));
res.stderr.on('data', (data) => {
console.error(`stderr: ${data.toString()}`);
reject(data.toString())
});
res.stdout.on('end', () => {
const result = (Buffer.concat(buffers)).toString();
console.log(`done, result:\n${result}`);
resolve(result);
});
});
};
// get results synchronously
(async() => {
console.log('await res:', await cp());
})();