Debo usar el método exec
en Nodejs porque necesito hacer algunas redirecciones de salida estándar y ejecutar más de un comando al mismo tiempo. Así que ejecuto el proceso hijo así:
let shell = null; const child_process = require('child_process') var command = 'activate python_environment & bokeh serve project_folder/ log/logger.log 2>&1'; shell = child_process.exec(command);
Necesito ps-tree para matar a los niños como hago en el código de abajo. Funciona bien en Ubuntu. Pero el problema es que obtengo un proceso huérfano (zombie) en Windows si no elimino los procesos secundarios.
const psTree = require('ps-tree') app.on('window-all-closed', function () { electron.app.quit() if(shell != null){ psTree(shell.pid, function (err, children) { children.map(function (p) { process.kill(p.PID); }); }); } });
El módulo ps-tree
usa el comando ps
en Linux y el comando wmic
en Windows. Entonces es multiplataforma. Pero no funciona en mi caso. ¿Hay una mejor manera de hacer esto?
Estaba explorando en el código fuente del ps-tree
pero no encontré nada.
Uso process.kill
porque también estoy usando electrones .
Me temo que debería intentar hacerlo manualmente obteniendo toda la lista de procesos con wmic
. Eso es lo que ps-tree
está tratando de hacer.
Nota: El módulo tree-kill
tampoco funcionó en ambas plataformas.
Actualizar
Bueno, encontré una solución fea. Guardo mi PID de proceso de python en un archivo externo a través del código de python os.getpid()
. Con esto puedo acceder al PID problemático dentro del nodo como este:
const fs = require('fs'); fs.readFile(filePath, 'utf-8', function (err, data) { process.kill(parseInt(data, 10)); app.quit(); });
Respondo por Windows porque es con el que tienes problemas.
Mirando el comando que ejecuta, me parece que su concatenación de dos comandos podría ser el culpable, por lo que intentaría prescindir de él.
Si no puede usar wmic es la mejor manera que conozco, la primera vez tendrá que verificar manualmente que sí. Una vez que tenga el criterio de selección, puede cerrar todo automáticamente. Mientras los procesos están ocupados, ejecute el comando wmic process>processes.txt
Luego, con un editor, verifique el archivo commandline
y busque en la línea de comandos de la columna una cadena común para todos los procesos que desea eliminar. Este será su criterio selecto. Dado que toda la línea de comando que creó el proceso está ahí con la ruta y los parámetros, esto no debería ser un problema.
Después de eso, debería poder cerrar todos esos procesos con el comando
wmic process Where "CommandLine Like '%my_select_criterium%'" Call Terminate
Utilizo esta técnica en un script de Ruby que llama a una aplicación Java que se comporta mal y sobre la que no tengo control.