- Reescrita la función stop para garantizar terminación completa de todos los procesos - Implementado mecanismo jerárquico de terminación: amigable → forzado → último recurso - Añadidos pasos de verificación adicionales para procesos persistentes - Mejorada función restart con múltiples intentos de terminación - Limpieza de archivos temporales y sockets para evitar conflictos - Mejor retroalimentación sobre procesos Node-RED en varios estados 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
380 lines
13 KiB
Bash
Executable file
380 lines
13 KiB
Bash
Executable file
#!/bin/bash
|
|
#Script : nodered.sh
|
|
#Apps : MRDEVS TOOLS
|
|
#Description : Inicia y Detiene el servicio de Nodered
|
|
#Author : Mauro Rosero Pérez
|
|
#Company Email : mauro@rosero.one
|
|
#Personal Email : mauro.rosero@gmail.com
|
|
#Created : 2024/12/01 15:27:00
|
|
#Modified : 2025/03/19 11:57:08
|
|
#Version : 1.2.0
|
|
#==============================================================================
|
|
# Derechos de Autor [2025] [Mauro Rosero P. <mauro@rosero.one>]
|
|
#==============================================================================
|
|
# Este programa es software libre: usted puede redistribuirlo y/o modificarlo
|
|
# bajo los términos de la Licencia Pública Affero General de GNU tal como
|
|
# lo publica la Free Software Foundation, ya sea la versión 3 de la licencia,
|
|
# o (a su elección) cualquier versión posterior.
|
|
#
|
|
# Este programa se distribuye con la esperanza de que sea útil,
|
|
# pero SIN NINGUNA GARANTÍA; sin siquiera la garantía implícita de
|
|
# COMERCIABILIDAD o IDONEIDAD PARA UN PROPÓSITO PARTICULAR. Consulte la
|
|
# Licencia Pública Affero General de GNU para obtener más detalles.
|
|
#
|
|
# Debería haber recibido una copia de la Licencia Pública Affero General
|
|
# junto con este programa. Si no la recibió, consulte <https://www.gnu.org/licenses/>.
|
|
|
|
# Configuración inicial
|
|
# Usar DEVELOPER_DIR de base.lib
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
BIN_BASE="bin"
|
|
BIN_LIBS="lib"
|
|
BIN_MESG="msg"
|
|
BIN_CFGS="config"
|
|
|
|
# Leer DEVSPATH desde el archivo de configuración o usar "devs" por defecto
|
|
if [ -f "$SCRIPT_DIR/config/devspath.dat" ]; then
|
|
DEVSPATH=$(cat "$SCRIPT_DIR/$BIN_CFGS/devspath.dat")
|
|
else
|
|
DEVSPATH="devs"
|
|
fi
|
|
|
|
BIN_HOME="$HOME/$DEVSPATH"
|
|
BIN_PATH=$BIN_HOME/$BIN_BASE
|
|
VERSION=$(cat "$BIN_HOME/$BIN_BASE/$BIN_CFGS/version")
|
|
|
|
# CHECK SHELL LANGUAGE
|
|
BIN_LANG=${LANG:0:2}
|
|
|
|
# Importar bibliotecas necesarias
|
|
if [ -f "${BIN_HOME}/${BIN_BASE}/${BIN_LIBS}/base.lib" ]; then
|
|
source "${BIN_HOME}/${BIN_BASE}/${BIN_LIBS}/base.lib"
|
|
# Cargar mensajes en el idioma del sistema o español por defecto
|
|
load_messages "${BIN_HOME}/${BIN_BASE}" "${BIN_MESG}" "${BIN_LANG}" "head"
|
|
title="${head_000} ${head_002}"
|
|
fi
|
|
|
|
# Verificar si es un proyecto de desarrollo y de tipo NodeJS
|
|
if [ ! -f "$PWD/.protype" ]; then
|
|
echo "${head_noproject}"
|
|
exit 1
|
|
fi
|
|
|
|
if [ "$(cat "$PWD/.protype")" != "nodejs" ]; then
|
|
echo "${head_002} ${head_warning}: Este script está diseñado para proyectos NodeJS."
|
|
read -p "¿Desea continuar de todos modos? (s/N): " CONTINUE
|
|
if [[ ! "$CONTINUE" =~ ^[Ss]$ ]]; then
|
|
echo "Operación cancelada."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Configuración de Node-RED
|
|
NODE_RED_DIR="$PWD"
|
|
NODE_RED_DATA="$NODE_RED_DIR/.node-red"
|
|
NODE_RED_PORT=${NODE_RED_PORT:-1880}
|
|
NODE_RED_CMD="npx node-red -u $NODE_RED_DATA -p $NODE_RED_PORT"
|
|
PID_FILE="$NODE_RED_DIR/nodered.pid"
|
|
LOG_FILE="$NODE_RED_DIR/nodered.log"
|
|
CONFIG_FILE="$NODE_RED_DATA/settings.js"
|
|
|
|
# Crear directorio de datos si no existe
|
|
mkdir -p "$NODE_RED_DATA" 2>/dev/null
|
|
|
|
start() {
|
|
if [ -f "$PID_FILE" ] && kill -0 "$(cat $PID_FILE)" 2>/dev/null; then
|
|
echo "Node-RED ya está en ejecución (PID $(cat $PID_FILE))"
|
|
echo "Abre http://localhost:$NODE_RED_PORT en tu navegador"
|
|
exit 1
|
|
fi
|
|
|
|
# Verificar si Node.js y npm están instalados
|
|
if ! command -v node &> /dev/null || ! command -v npm &> /dev/null; then
|
|
echo "Error: Node.js y npm son requeridos pero no están instalados."
|
|
echo "Instala Node.js con el comando: bin/npm_install.sh"
|
|
exit 1
|
|
fi
|
|
|
|
# Verificar si node-red está disponible localmente
|
|
if ! npm list -g node-red &> /dev/null && ! npm list node-red &> /dev/null; then
|
|
echo "Node-RED no está instalado. Instalando localmente..."
|
|
npm install --save node-red
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error al instalar Node-RED. Verifica tu conexión a internet."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
echo "Iniciando Node-RED en el puerto $NODE_RED_PORT..."
|
|
mkdir -p "$NODE_RED_DATA"
|
|
nohup $NODE_RED_CMD > "$LOG_FILE" 2>&1 &
|
|
echo $! > "$PID_FILE"
|
|
|
|
# Esperar a que Node-RED esté listo
|
|
echo "Iniciando Node-RED (PID $(cat $PID_FILE))..."
|
|
echo "Esperando a que el servicio esté disponible..."
|
|
|
|
for i in {1..30}; do
|
|
if grep -q "Server now running" "$LOG_FILE" 2>/dev/null; then
|
|
echo "Node-RED iniciado correctamente."
|
|
echo "Abre http://localhost:$NODE_RED_PORT en tu navegador"
|
|
return 0
|
|
fi
|
|
sleep 1
|
|
echo -n "."
|
|
done
|
|
|
|
echo ""
|
|
echo "Node-RED parece estar tardando en iniciar. Verifica $LOG_FILE para más detalles."
|
|
echo "Si todo está bien, abre http://localhost:$NODE_RED_PORT en tu navegador"
|
|
}
|
|
|
|
stop() {
|
|
# Variable para seguir si se detectaron procesos
|
|
local found_processes=0
|
|
|
|
echo "Deteniendo Node-RED..."
|
|
|
|
# Matar todos los procesos recursivamente y de forma agresiva
|
|
kill_all_nodered() {
|
|
echo "Buscando procesos Node-RED..."
|
|
|
|
# Buscar todos los procesos relacionados con Node-RED
|
|
local NR_PIDS=$(pgrep -f "node-red" 2>/dev/null || echo "")
|
|
|
|
# Si no se encontraron procesos
|
|
if [ -z "$NR_PIDS" ]; then
|
|
return 1
|
|
fi
|
|
|
|
# Procesar cada PID encontrado
|
|
found_processes=1
|
|
echo "Terminando procesos Node-RED: $NR_PIDS"
|
|
|
|
# Primera pasada: intento amigable (SIGTERM)
|
|
for pid in $NR_PIDS; do
|
|
echo "Enviando SIGTERM al proceso $pid..."
|
|
kill $pid 2>/dev/null
|
|
done
|
|
|
|
# Esperar un momento
|
|
sleep 2
|
|
|
|
# Segunda pasada: verificar y forzar si es necesario
|
|
local REMAINING_PIDS=$(pgrep -f "node-red" 2>/dev/null || echo "")
|
|
if [ -n "$REMAINING_PIDS" ]; then
|
|
echo "Algunos procesos persisten. Forzando terminación (SIGKILL)..."
|
|
for pid in $REMAINING_PIDS; do
|
|
echo "Forzando terminación del proceso $pid..."
|
|
kill -9 $pid 2>/dev/null
|
|
done
|
|
|
|
# Esperar un poco más
|
|
sleep 1
|
|
|
|
# Verificación final
|
|
local FINAL_CHECK=$(pgrep -f "node-red" 2>/dev/null || echo "")
|
|
if [ -n "$FINAL_CHECK" ]; then
|
|
echo "ADVERTENCIA: Algunos procesos de Node-RED aún persisten: $FINAL_CHECK"
|
|
echo "Puede ser necesario reiniciar el sistema para liberarlos completamente."
|
|
return 2
|
|
fi
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
# Verificar primero si el archivo PID existe
|
|
if [ -f "$PID_FILE" ]; then
|
|
echo "Usando archivo PID: $PID_FILE"
|
|
if kill -0 "$(cat $PID_FILE)" 2>/dev/null; then
|
|
local PID=$(cat "$PID_FILE")
|
|
echo "PID válido encontrado: $PID"
|
|
|
|
# Enviar señal SIGTERM para terminar amigablemente
|
|
kill $PID 2>/dev/null
|
|
found_processes=1
|
|
|
|
# Esperar brevemente
|
|
sleep 2
|
|
else
|
|
echo "Archivo PID existe pero el proceso no está activo"
|
|
fi
|
|
|
|
# Eliminar el archivo PID en cualquier caso
|
|
rm -f "$PID_FILE"
|
|
fi
|
|
|
|
# Buscar y matar todos los procesos de Node-RED
|
|
kill_all_nodered
|
|
|
|
# Usar pkill como último recurso
|
|
pkill -9 -f "node-red" 2>/dev/null
|
|
|
|
# Verificación final y mensaje
|
|
if pgrep -f "node-red" > /dev/null; then
|
|
echo "ERROR: No se pudo detener completamente Node-RED."
|
|
echo "Verifique manualmente los procesos con: ps aux | grep node-red"
|
|
return 1
|
|
elif [ $found_processes -eq 1 ]; then
|
|
echo "Node-RED detenido correctamente."
|
|
return 0
|
|
else
|
|
echo "No se encontraron procesos de Node-RED en ejecución."
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
status() {
|
|
# Primera verificación: archivo PID existe y el proceso está en ejecución
|
|
if [ -f "$PID_FILE" ] && kill -0 "$(cat $PID_FILE)" 2>/dev/null; then
|
|
echo "Node-RED está en ejecución:"
|
|
echo " - PID: $(cat $PID_FILE)"
|
|
echo " - URL: http://localhost:$NODE_RED_PORT"
|
|
echo " - Directorio de datos: $NODE_RED_DATA"
|
|
echo " - Archivo de log: $LOG_FILE"
|
|
|
|
# Mostrar tiempo de ejecución si está disponible
|
|
if command -v ps &>/dev/null; then
|
|
local start_time=$(ps -p $(cat $PID_FILE) -o lstart= 2>/dev/null)
|
|
[ -n "$start_time" ] && echo " - Iniciado: $start_time"
|
|
fi
|
|
|
|
# Verificar si el servicio está realmente respondiendo
|
|
if command -v curl &>/dev/null; then
|
|
if curl -s "http://localhost:$NODE_RED_PORT" >/dev/null; then
|
|
echo " - Estado: Respondiendo"
|
|
else
|
|
echo " - Estado: Proceso en ejecución pero no responde HTTP"
|
|
fi
|
|
fi
|
|
return 0
|
|
fi
|
|
|
|
# Segunda verificación: buscar procesos de Node-RED sin archivo PID
|
|
local NR_PIDS=$(pgrep -f "node-red" | tr "\n" " ")
|
|
|
|
if [ -n "$NR_PIDS" ]; then
|
|
echo "Node-RED está en ejecución, pero sin archivo PID correcto:"
|
|
|
|
for pid in $NR_PIDS; do
|
|
echo " - PID: $pid"
|
|
|
|
# Mostrar información adicional si está disponible
|
|
if command -v ps &>/dev/null; then
|
|
local cmd_line=$(ps -p $pid -o cmd= 2>/dev/null)
|
|
[ -n "$cmd_line" ] && echo " - Comando: $cmd_line"
|
|
|
|
local start_time=$(ps -p $pid -o lstart= 2>/dev/null)
|
|
[ -n "$start_time" ] && echo " - Iniciado: $start_time"
|
|
fi
|
|
done
|
|
|
|
echo " - URL: http://localhost:$NODE_RED_PORT (probable)"
|
|
|
|
# Verificar si el servicio está realmente respondiendo
|
|
if command -v curl &>/dev/null; then
|
|
if curl -s "http://localhost:$NODE_RED_PORT" >/dev/null; then
|
|
echo " - Estado: Respondiendo"
|
|
else
|
|
echo " - Estado: Proceso en ejecución pero no responde HTTP"
|
|
fi
|
|
fi
|
|
|
|
echo "NOTA: Ejecute 'stop' y 'start' para regenerar el archivo PID correcto."
|
|
return 0
|
|
fi
|
|
|
|
# Si no se encontró ningún proceso
|
|
echo "Node-RED no está en ejecución."
|
|
# Limpiar archivos PID huérfanos si existen
|
|
[ -f "$PID_FILE" ] && rm -f "$PID_FILE"
|
|
return 1
|
|
}
|
|
|
|
restart() {
|
|
echo "Reiniciando Node-RED..."
|
|
|
|
# Forzar detención completa
|
|
stop
|
|
|
|
# Verificación adicional y limpieza
|
|
for i in {1..3}; do
|
|
if pgrep -f "node-red" > /dev/null; then
|
|
echo "Intento adicional $i: Forzando terminación de procesos persistentes..."
|
|
pkill -9 -f "node-red" 2>/dev/null
|
|
sleep 2
|
|
else
|
|
break
|
|
fi
|
|
done
|
|
|
|
# Comprobar una última vez
|
|
if pgrep -f "node-red" > /dev/null; then
|
|
echo "ADVERTENCIA: No fue posible detener completamente Node-RED."
|
|
echo "Los nuevos procesos podrían comportarse de manera inesperada."
|
|
fi
|
|
|
|
# Limpiar cualquier archivo temporal o socket que pudiera causar problemas
|
|
rm -f /tmp/node-red-*.sock 2>/dev/null
|
|
|
|
# Esperar a que el sistema se estabilice
|
|
sleep 3
|
|
|
|
# Iniciar Node-RED
|
|
start
|
|
}
|
|
|
|
install_deps() {
|
|
echo "Instalando dependencias de Node-RED..."
|
|
|
|
# Verificar si Node.js y npm están instalados
|
|
if ! command -v node &> /dev/null || ! command -v npm &> /dev/null; then
|
|
echo "Error: Node.js y npm son requeridos pero no están instalados."
|
|
echo "Instala Node.js con el comando: bin/npm_install.sh"
|
|
exit 1
|
|
fi
|
|
|
|
# Instalar o actualizar Node-RED
|
|
npm install --save node-red
|
|
|
|
# Instalar paquetes comunes útiles para IoT
|
|
npm install --save node-red-dashboard node-red-node-serialport node-red-contrib-mqtt-broker
|
|
|
|
echo "Dependencias instaladas correctamente."
|
|
}
|
|
|
|
logs() {
|
|
if [ -f "$LOG_FILE" ]; then
|
|
if command -v tail &>/dev/null; then
|
|
echo "Mostrando las últimas líneas del log (Ctrl+C para salir):"
|
|
tail -f "$LOG_FILE"
|
|
else
|
|
echo "Contenido del archivo de log:"
|
|
cat "$LOG_FILE"
|
|
fi
|
|
else
|
|
echo "No hay archivo de log disponible."
|
|
fi
|
|
}
|
|
|
|
case "$1" in
|
|
start) start ;;
|
|
stop) stop ;;
|
|
restart) restart ;;
|
|
status) status ;;
|
|
install) install_deps ;;
|
|
logs) logs ;;
|
|
*)
|
|
echo "Node-RED Administración"
|
|
echo "Uso: $0 {start|stop|restart|status|install|logs}"
|
|
echo ""
|
|
echo "Comandos:"
|
|
echo " start - Inicia el servidor Node-RED"
|
|
echo " stop - Detiene el servidor Node-RED"
|
|
echo " restart - Reinicia el servidor Node-RED"
|
|
echo " status - Muestra el estado del servidor"
|
|
echo " install - Instala/actualiza Node-RED y dependencias comunes"
|
|
echo " logs - Muestra los logs en tiempo real"
|
|
;;
|
|
esac
|