我有这个node.js代码:
const k = cp.spawn('bash');
k.stdin.end(`
set -e;
echo; echo; echo 'du results:';
( cd "${extractDir}" && tar -xzvf "${createTarball.pack.value}" ) > /dev/null;
find "${extractDir}/package" -type f | xargs du --threshold=500KB;
`);
k.stdout.pipe(pt(chalk.redBright('this is a big file (>500KB) according to du: '))).pipe(process.stdout);
k.stderr.pipe(pt(chalk.magenta('du stderr: '))).pipe(process.stderr);
问题是多个孙子孙将把所有的stdout / stderr都写给父母。
我想改成这样:
const pid = process.pid;
const k = cp.spawn('bash');
k.stdin.end(`
set -e;
exec 3<>/proc/${pid}/fd/1
echo > 3 ; echo > 3; echo 'du results:' > 3;
( cd "${extractDir}" && tar -xzvf "${createTarball.pack.value}" ) > /dev/null;
find "${extractDir}/package" -type f | xargs du --threshold=500KB ;
`);
k.stdout.pipe(pt(chalk.redBright('this is a big file (>500KB) according to du: '))).pipe(process.stdout);
k.stderr.pipe(pt(chalk.magenta('du stderr: '))).pipe(process.stderr);
但是该技术不适用于MacOS,因为Mac不具有/ proc / pid fs功能。有人知道我正在尝试做什么,也许是一个好的解决方法?
答案 0 :(得分:1)
安装Live Example或其他从节点进行原始syscall的方法。然后,以1
作为参数进行系统调用libsys,并将结果存储到变量fd
中。完成此操作后,fd
将是多个文件描述符,该文件描述符是节点标准输出的副本,并且将由子进程继承。此时,只需从bash中删除exec 3<>/proc/${pid}/fd/1
,然后用>&3
替换所有>&${fd}
。
答案 1 :(得分:1)
所以我以另一种方式解决了这个问题,OP有点像XY问题-因为我在MacOS上并且没有/proc/<pid>
文件,所以我基本上使用mkfifo:
首先我们称之为:
mkfifo "$fifoDir/fifo"
然后我们有
const fifo = cp.spawn('bash');
fifo.stdout.setEncoding('utf8');
fifo.stdout
.pipe(pt(chalk.yellow.bold('warning: this is a big file (>5KB) according to du: ')))
.pipe(process.stdout);
fifo.stdin.end(`
while true; do
cat "${fifoDir}/fifo"
done
`);
const k = cp.spawn('bash');
k.stdin.end(`
set -e;
echo; echo 'du results:';
tar -xzvf "${createTarball.pack.value}" -C "${extractDir}" > /dev/null;
${cmd} > "${fifoDir}/fifo";
kill -INT ${fifo.pid};
`);
k.stdout.pipe(process.stdout);
k.stderr.pipe(pt(chalk.magenta('du stderr: '))).pipe(process.stderr);
k.once('exit', code => {
if (code > 0) {
log.error('Could not run cmd:', cmd);
}
cb(code);
});
},
“ fifo”子进程是处理k的同级进程,当您查看上述代码块时,这很明显,并且“ fifo”进程最终处理了k进程的一个子进程的标准输出-它们通过命名管道(mkfifo)进行相互通信。