Nodejs spawn 之stdio

2019-10-15  本文已影响0人  黑曼巴yk

spawn,exec,execFile和fork关系

exec 
  │
execFile         fork
  │               │     
  └─────spawn─────┘          用户层面
           │
-----------│------------------------
           │
           │                  nodejs内部
           │                   
     spawn(位于lib/internal/child_process.js)

从上图可以看出,在用户层面其他的三个函数都调用了child_process.spwan

子进程的stdio(标准输入输出)

  1. options.stdio的值是字符串时,有以下几种取值
  1. 当options.stdio值是数组的时候,前三个元素分别代表stdin,stdout,stderr。如果数组的元素大于3,则会在父子进程之间建立额外的通讯通道,他们可能是下面的值.

例子

  1. pipe
    绑定到父进程的process.stdio中
const child_process = require("child_process");
const script = (function(data) {
  console.log(data);
}).toString();
const node = child_process.spawn("node", ["-e", `( ${script}("pipe,只能通过父进程将它输出") )`], {
  stdio: 'pipe'
});
node.stdout.on('data', data => {
  console.log(data.toString())
})
  1. inherit
const child_process = require("child_process");
const script = (function(data) {
  console.log(data);
}).toString();
child_process.spawn("node", ["-e", `( ${script}("inherit,这一般个会写到控制台") )`], {
  stdio: [process.stdin, process.stdout, process.stderr]
  // 和 stdio: 'inherit'相似
});
  1. 绑定文件描述符(fd)
const child_process = require("child_process");
const fd = require("fs").openSync("./node.log", "w+");
const script = (function(data) {
  console.log(data);
}).toString();

const node = child_process.spawn("node", ["-e", `( ${script}("整数fd,这一般个会写到某个文件") )`], {
  //stdio绑定到文件描述符fd,它代表文件node.log,因此会输出到该文件
  stdio: [process.stdin, fd, fd]
});
  1. 绑定stream
const child_process = require("child_process");
const fd = require("fs").openSync("./node.log", "w+");
const script = (function(data) {
  console.log(data);
}).toString();


const writableStream = require("fs").createWriteStream(null, {
  flags: "a",
  fd,
});
child_process.spawn("node", ["-e", `( ${script}("stream,这一般个会写到某个文件") )`], {
  //输出到流所代表的目的地,注意这个流必须要有文件描述符,否则会失败
  //这个例子中它会输出到文件node.log
  stdio: [process.stdin, writableStream, fd]
});
  1. ipc通道
// parent.js
const child_process = require("child_process");

const node = child_process.spawn("node",['./child.js'], {
  shell:false,
  stdio: ['inherit', 'inherit', 'inherit','ipc']
});

node.send({from: 'parent'});
// child.js
process.on('message', function(m){
  console.log('message from parent: ' + JSON.stringify(m));
});
process.send({from: 'child'});

detached 和守护进程

生成子进程的时候如果传递了detached=true,则使得子进程成为新的sessiongroup的leader

const child_process = require("child_process");
const ping = child_process.spawn("ping", ["localhost"], {
    detached:true,
    stdio: 'ignore'
});
ping.unref();

需要成为守护进程,必须要做到以下几点

refer

https://cnodejs.org/topic/5aa0e25a19b2e3db18959bee

上一篇下一篇

猜你喜欢

热点阅读