使用 node.js 将文件描述符传递给子进程
pass on file descriptors to child process with node.js
为了在我的一个项目中使用 bashcov
,我需要一种方法将所有文件描述符从 node.js 传递给子进程。
我创建了这些测试程序:
$ head -n20 m.sh r.js s.sh
==> m.sh <==
#! /usr/bin/env bash
set -e
exec 3<>messages
echo see when we can see the file descriptor we created
echo from main bash program:
ls -l /proc/$$/fd/
echo
echo from bash subprogram called directly:
./s.sh
echo
node r.js ./s.sh
exec 3>&-
==> r.js <==
const run = function(cmd) {
return require('child_process').spawnSync(cmd[0], cmd.slice(1), {
stdio: 'inherit',
});
}
console.log('from javascript program:');
run(['ls', '-l', `/proc/${process.pid}/fd/`]);
console.log('\nfrom bash subprogram called from js:');
run(process.argv.slice(2))
==> s.sh <==
#! /usr/bin/env bash
set -e
ls -l /proc/$$/fd/
主程序 m.sh
列出它的所有文件描述符,然后调用一个 bash 我称为“子程序”的程序 s.sh
它也列出了它的所有文件fds。然后我调用一个 js 程序 r.js
列出其可用的 fds,然后使用 child_process
库再次调用 s.sh
。
这是结果:
$ ./m.sh
see when we can see the file descriptor we created
from main bash program:
total 0
lrwx------ 1 me me 64 Apr 16 12:16 0 -> /dev/pts/2
l-wx------ 1 me me 64 Apr 16 12:16 1 -> pipe:[256648]
lrwx------ 1 me me 64 Apr 16 12:16 2 -> /dev/pts/2
lr-x------ 1 me me 64 Apr 16 12:16 255 -> /home/me/bashcov/m.sh
lrwx------ 1 me me 64 Apr 16 12:16 3 -> /home/me/bashcov/messages
from bash subprogram called directly:
total 0
lrwx------ 1 me me 64 Apr 16 12:16 0 -> /dev/pts/2
l-wx------ 1 me me 64 Apr 16 12:16 1 -> pipe:[256648]
lrwx------ 1 me me 64 Apr 16 12:16 2 -> /dev/pts/2
lr-x------ 1 me me 64 Apr 16 12:16 255 -> /home/me/bashcov/s.sh
lrwx------ 1 me me 64 Apr 16 12:16 3 -> /home/me/bashcov/messages
from javascript program:
total 0
lrwx------ 1 me me 64 Apr 16 12:16 0 -> /dev/pts/2
l-wx------ 1 me me 64 Apr 16 12:16 1 -> pipe:[256648]
lrwx------ 1 me me 64 Apr 16 12:16 10 -> anon_inode:[eventpoll]
lr-x------ 1 me me 64 Apr 16 12:16 11 -> pipe:[256661]
l-wx------ 1 me me 64 Apr 16 12:16 12 -> pipe:[256661]
lrwx------ 1 me me 64 Apr 16 12:16 13 -> anon_inode:[eventfd]
lrwx------ 1 me me 64 Apr 16 12:16 14 -> anon_inode:[eventpoll]
lr-x------ 1 me me 64 Apr 16 12:16 15 -> pipe:[258179]
l-wx------ 1 me me 64 Apr 16 12:16 16 -> pipe:[258179]
lrwx------ 1 me me 64 Apr 16 12:16 17 -> anon_inode:[eventfd]
lr-x------ 1 me me 64 Apr 16 12:16 18 -> /dev/null
lrwx------ 1 me me 64 Apr 16 12:16 19 -> anon_inode:[eventpoll]
lrwx------ 1 me me 64 Apr 16 12:16 2 -> /dev/pts/2
lr-x------ 1 me me 64 Apr 16 12:16 20 -> pipe:[258182]
l-wx------ 1 me me 64 Apr 16 12:16 21 -> pipe:[258182]
lrwx------ 1 me me 64 Apr 16 12:16 22 -> anon_inode:[eventfd]
lrwx------ 1 me me 64 Apr 16 12:16 3 -> /home/me/bashcov/messages
lrwx------ 1 me me 64 Apr 16 12:16 4 -> anon_inode:[eventpoll]
lr-x------ 1 me me 64 Apr 16 12:16 5 -> pipe:[258177]
l-wx------ 1 me me 64 Apr 16 12:16 6 -> pipe:[258177]
lr-x------ 1 me me 64 Apr 16 12:16 7 -> pipe:[258178]
l-wx------ 1 me me 64 Apr 16 12:16 8 -> pipe:[258178]
lrwx------ 1 me me 64 Apr 16 12:16 9 -> anon_inode:[eventfd]
from bash subprogram called from js:
total 0
lrwx------ 1 me me 64 Apr 16 12:16 0 -> /dev/pts/2
l-wx------ 1 me me 64 Apr 16 12:16 1 -> pipe:[256648]
lrwx------ 1 me me 64 Apr 16 12:16 2 -> /dev/pts/2
lr-x------ 1 me me 64 Apr 16 12:16 255 -> /home/me/bashcov/s.sh
您可以看到,当从 node.js 调用 s.sh
时,它无法访问我创建的文件描述符 3
。 bash 将其传递给它调用的 bash 程序,以及它调用的节点程序,但节点不会。
我刚刚 运行 解决了这个问题 python () and the solution turned out to be to add the param close_fds=False
. ()
如果我把这个实验中的js程序换成ruby或者make程序,就可以正常工作了。
有没有办法告诉 node.js 的 child_process
传递 child_process 上所有打开的文件描述符?
将 stdio: 'inherit'
替换为 stdio: [0, 1, 2, 3]
。 'inherit'
is shorthand for [0, 1, 2]
, per the documentation, 所以如果你想要 FD 3 也被传递,你需要手动添加它。除了手动创建一个包含所有数字的数组之外,我看不到告诉它继承每个 FD 的方法。
为了在我的一个项目中使用 bashcov
,我需要一种方法将所有文件描述符从 node.js 传递给子进程。
我创建了这些测试程序:
$ head -n20 m.sh r.js s.sh
==> m.sh <==
#! /usr/bin/env bash
set -e
exec 3<>messages
echo see when we can see the file descriptor we created
echo from main bash program:
ls -l /proc/$$/fd/
echo
echo from bash subprogram called directly:
./s.sh
echo
node r.js ./s.sh
exec 3>&-
==> r.js <==
const run = function(cmd) {
return require('child_process').spawnSync(cmd[0], cmd.slice(1), {
stdio: 'inherit',
});
}
console.log('from javascript program:');
run(['ls', '-l', `/proc/${process.pid}/fd/`]);
console.log('\nfrom bash subprogram called from js:');
run(process.argv.slice(2))
==> s.sh <==
#! /usr/bin/env bash
set -e
ls -l /proc/$$/fd/
主程序 m.sh
列出它的所有文件描述符,然后调用一个 bash 我称为“子程序”的程序 s.sh
它也列出了它的所有文件fds。然后我调用一个 js 程序 r.js
列出其可用的 fds,然后使用 child_process
库再次调用 s.sh
。
这是结果:
$ ./m.sh
see when we can see the file descriptor we created
from main bash program:
total 0
lrwx------ 1 me me 64 Apr 16 12:16 0 -> /dev/pts/2
l-wx------ 1 me me 64 Apr 16 12:16 1 -> pipe:[256648]
lrwx------ 1 me me 64 Apr 16 12:16 2 -> /dev/pts/2
lr-x------ 1 me me 64 Apr 16 12:16 255 -> /home/me/bashcov/m.sh
lrwx------ 1 me me 64 Apr 16 12:16 3 -> /home/me/bashcov/messages
from bash subprogram called directly:
total 0
lrwx------ 1 me me 64 Apr 16 12:16 0 -> /dev/pts/2
l-wx------ 1 me me 64 Apr 16 12:16 1 -> pipe:[256648]
lrwx------ 1 me me 64 Apr 16 12:16 2 -> /dev/pts/2
lr-x------ 1 me me 64 Apr 16 12:16 255 -> /home/me/bashcov/s.sh
lrwx------ 1 me me 64 Apr 16 12:16 3 -> /home/me/bashcov/messages
from javascript program:
total 0
lrwx------ 1 me me 64 Apr 16 12:16 0 -> /dev/pts/2
l-wx------ 1 me me 64 Apr 16 12:16 1 -> pipe:[256648]
lrwx------ 1 me me 64 Apr 16 12:16 10 -> anon_inode:[eventpoll]
lr-x------ 1 me me 64 Apr 16 12:16 11 -> pipe:[256661]
l-wx------ 1 me me 64 Apr 16 12:16 12 -> pipe:[256661]
lrwx------ 1 me me 64 Apr 16 12:16 13 -> anon_inode:[eventfd]
lrwx------ 1 me me 64 Apr 16 12:16 14 -> anon_inode:[eventpoll]
lr-x------ 1 me me 64 Apr 16 12:16 15 -> pipe:[258179]
l-wx------ 1 me me 64 Apr 16 12:16 16 -> pipe:[258179]
lrwx------ 1 me me 64 Apr 16 12:16 17 -> anon_inode:[eventfd]
lr-x------ 1 me me 64 Apr 16 12:16 18 -> /dev/null
lrwx------ 1 me me 64 Apr 16 12:16 19 -> anon_inode:[eventpoll]
lrwx------ 1 me me 64 Apr 16 12:16 2 -> /dev/pts/2
lr-x------ 1 me me 64 Apr 16 12:16 20 -> pipe:[258182]
l-wx------ 1 me me 64 Apr 16 12:16 21 -> pipe:[258182]
lrwx------ 1 me me 64 Apr 16 12:16 22 -> anon_inode:[eventfd]
lrwx------ 1 me me 64 Apr 16 12:16 3 -> /home/me/bashcov/messages
lrwx------ 1 me me 64 Apr 16 12:16 4 -> anon_inode:[eventpoll]
lr-x------ 1 me me 64 Apr 16 12:16 5 -> pipe:[258177]
l-wx------ 1 me me 64 Apr 16 12:16 6 -> pipe:[258177]
lr-x------ 1 me me 64 Apr 16 12:16 7 -> pipe:[258178]
l-wx------ 1 me me 64 Apr 16 12:16 8 -> pipe:[258178]
lrwx------ 1 me me 64 Apr 16 12:16 9 -> anon_inode:[eventfd]
from bash subprogram called from js:
total 0
lrwx------ 1 me me 64 Apr 16 12:16 0 -> /dev/pts/2
l-wx------ 1 me me 64 Apr 16 12:16 1 -> pipe:[256648]
lrwx------ 1 me me 64 Apr 16 12:16 2 -> /dev/pts/2
lr-x------ 1 me me 64 Apr 16 12:16 255 -> /home/me/bashcov/s.sh
您可以看到,当从 node.js 调用 s.sh
时,它无法访问我创建的文件描述符 3
。 bash 将其传递给它调用的 bash 程序,以及它调用的节点程序,但节点不会。
我刚刚 运行 解决了这个问题 python (close_fds=False
. (
如果我把这个实验中的js程序换成ruby或者make程序,就可以正常工作了。
有没有办法告诉 node.js 的 child_process
传递 child_process 上所有打开的文件描述符?
将 stdio: 'inherit'
替换为 stdio: [0, 1, 2, 3]
。 'inherit'
is shorthand for [0, 1, 2]
, per the documentation, 所以如果你想要 FD 3 也被传递,你需要手动添加它。除了手动创建一个包含所有数字的数组之外,我看不到告诉它继承每个 FD 的方法。