Estoy tratando de crear un proceso secundario usando spawn() con su propia terminal
padre.js:
const spawn = require('child_process').spawn; console.log('started parent process...'); //this should be printed in the parent terminal const child = spawn('start node', [`child.js`], { cwd:__dirname, shell: true, stdio: [null, null, null, 'pipe'] }); const Name = 'general kenobi'; child.stdio[3].write(Name); child.stdio[3].on('data', (data) => { console.log('data=>', data.toString()); child.kill(); });niño.js:
console.log('started child process...'); (async()=>{ await new Promise(r=>setTimeout(r,3000)); try{ let net = require('net'); let pipe = new net.Socket({ fd: 3 }); pipe.on('data',(data)=>{ pipe.write(`hello there ${data}`); }); }catch(err){console.log(err)} await new Promise(r => setTimeout(r, 3000)); })(); los datos esperados deberían ser data=> hello there general kenobi pero da este error en la terminal secundaria
throw new ERR_INVALID_FD_TYPE(type); ^ TypeError [ERR_INVALID_FD_TYPE]: Unsupported fd type: UNKNOWN at new NodeError (node:internal/errors:371:5) at createHandle (node:net:152:9) at new Socket (node:net:340:20) at Object.<anonymous> (C:\...\parent.js:4:12) at Module._compile (node:internal/modules/cjs/loader:1101:14) at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10) at Module.load (node:internal/modules/cjs/loader:981:32) at Function.Module._load (node:internal/modules/cjs/loader:822:12) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12) at node:internal/main/run_main_module:17:47 { code: 'ERR_INVALID_FD_TYPE' }
No pude encontrar muchas referencias, así que usé este video como guía.
(trate de evitar un paquete de terceros mientras responde)
Elimine shell: true y cambie el comando a 'nodo' en el archivo parent.js .
const child = spawn('node', [`child.js`], { cwd:__dirname, stdio: [null, null, null, 'pipe'] }); En lugar de usar spawn en sí mismo, al agregar shell: true , spawn usará el shell de su sistema para ejecutar ese comando. en general, sugiero usar spawn puro sin usar caparazón. El riesgo se reducirá sin tocar la carcasa directamente y el problema de la tubería de datos.
Primero, como otros mencionaron en los comentarios, 'start node' debería ser solo 'node' . Comparé el video que vinculaste y descubrí que si cambias 'node' (el argumento de spawn ) a 'process.execPath' ¡funciona mágicamente!
padre.js:
const spawn = require('child_process').spawn; console.log('started parent process...'); //this should be printed in the parent terminal const child = spawn(process.execPath, [`child.js`], { //cwd:__dirname, //shell: true, stdio: [null, null, null, 'pipe'] }); const Name = 'general kenobi'; child.stdio[3].write(Name); child.stdio[3].on('data', (data) => { console.log('data=>', data.toString()); child.kill(); });Actualmente no estoy seguro de por qué sucede esto. ¡Podría ser solo un error, supongo! Por ahora, pensé que tal vez solo la solución te ayude.
Si registra el process.execPath y, como se mencionó en los documentos , devuelve la ruta absoluta al nodo y también resuelve todos los enlaces simbólicos. Este podría ser el problema con el spawn.
Además, si usa shell: true en las opciones, el proceso secundario no se elimina. No sé si es el comportamiento esperado para ti o no.
Actualizar:
El problema en mi ubuntu se debió al uso del nodo de los paquetes instantáneos, y probablemente sea un error del intento instantáneo de aislar el proceso.
Abrí un tema en Snapcraft y probablemente sea un error conocido con las instantáneas sobre el descriptor de archivo. Puede leer más sobre las soluciones alternativas y el error en el enlace.
Actualización 2:
Otro método para lograr generar el mensaje en la segunda línea de comando.
padre.js:
const spawn = require('child_process').spawn; console.log('started parent process...'); const child = spawn('node', ['child.js'], { cwd: __dirname, stdio: [null, null, null, 'ipc'], }); const Name = 'general kenobi'; child.send(Name); child.on('message', (data) => { console.log('data=>', data); // child.kill(); });niño.js:
const spawn = require('child_process').spawn; console.log('started child process...'); process.on('message', (data) => { process.send(`hello there ${data}`); const cmd = spawn('start', ['cmd.exe', '/k', `echo hello there ${data}`], { cwd: __dirname, shell: true, }); });