15%

Ahorra 15%<\/span> en todos los servicios de hosting

Pon a prueba tus habilidades y obtén Descuento<\/span> en cualquier plan de hosting

Usa el código:

Skills
Comenzar
10.11.2023

Cómo habilitar la carga automática de scripts en Ubuntu: tres métodos listos para producción

Habilitar la carga automática de scripts en Ubuntu significa configurar el sistema operativo para ejecutar automáticamente uno o más scripts de shell o servicios al inicio del sistema, sin ninguna intervención manual. Esto se logra mediante tres mecanismos principales: el directorio /etc/init.d/ basado en SysVinit heredado, el shim de compatibilidad /etc/rc.local, y el moderno marco de unidades de servicio systemd — siendo este último el enfoque autorizado y recomendado en todas las versiones de Ubuntu desde la 15.04 en adelante.

Para los administradores de sistemas que ejecutan cargas de trabajo en un entorno de VPS Hosting, la automatización del inicio no es una comodidad — es un requisito de fiabilidad. Una entrada de inicio automático mal configurada o ausente significa que los demonios críticos, los agentes de monitoreo, los scripts de copia de seguridad o las configuraciones de red personalizadas fallan silenciosamente al iniciarse después de un reinicio, causando interrupciones del servicio que son difíciles de diagnosticar a posteriori.

Por Qué la Automatización de Scripts de Inicio es Importante en Servidores Ubuntu

Cada servidor Ubuntu en producción acumula scripts operativos con el tiempo: rutinas de precalentamiento de bases de datos, disparadores de rotación de registros, inicializadores de túneles VPN, cargadores de reglas de firewall y verificaciones de salud de aplicaciones. Sin un mecanismo de carga automática estructurado, estos scripts dependen completamente de la ejecución manual — un solo paso omitido después de una actualización del kernel o un reinicio de emergencia puede desencadenar una interrupción del servicio.

El ecosistema de automatización de inicio de Ubuntu ha evolucionado significativamente:

  • SysVinit (anterior a Ubuntu 15.04): Secuencial, lento, basado en scripts. Cada servicio bloqueaba al siguiente.
  • Upstart (Ubuntu 6.10–15.04): Basado en eventos, más rápido, pero ahora obsoleto.
  • systemd (Ubuntu 15.04+): Activación de servicios en paralelo, grafos de dependencias, activación por socket, control de recursos basado en cgroup y registro estructurado mediante journald.

Comprender con qué capa está trabajando — y por qué — le evita implementar una solución funcional en un entorno de prueba que falla silenciosamente en producción.

Método 1: Uso del Directorio /etc/init.d/ (SysVinit / Scripts LSB)

Cómo Funciona

El directorio /etc/init.d/ es el hogar tradicional de los scripts de inicio de Linux Standard Base (LSB). Cada script en este directorio es un script de shell que responde a comandos estandarizados: start, stop, restart, status y opcionalmente reload. La utilidad update-rc.d crea enlaces simbólicos en los directorios de nivel de ejecución /etc/rcN.d/, determinando cuándo y en qué orden se ejecuta el script durante las secuencias de arranque y apagado.

En los sistemas Ubuntu modernos que ejecutan systemd, estos scripts aún son compatibles a través de una capa de compatibilidad llamada systemd-sysv-generator, que convierte automáticamente los scripts de inicio LSB en unidades systemd transitorias. Esto significa que sus scripts /etc/init.d/ seguirán ejecutándose, pero están envueltos por systemd en lugar de ser ejecutados directamente por SysVinit.

Implementación Paso a Paso

Paso 1: Cree su script

Escriba su script y asegúrese de que siga la convención de encabezado LSB. Un ejemplo mínimo y seguro para producción:

#!/bin/bash
### BEGIN INIT INFO
# Provides:          examplescript
# Required-Start:    $remote_fs $syslog $network
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Example autoload script
# Description:       Runs a custom initialization task at boot
### END INIT INFO

case "$1" in
  start)
    echo "Starting examplescript..."
    /usr/local/bin/examplescript.sh &
    ;;
  stop)
    echo "Stopping examplescript..."
    pkill -f examplescript.sh
    ;;
  restart)
    $0 stop
    $0 start
    ;;
  status)
    pgrep -f examplescript.sh > /dev/null && echo "Running" || echo "Stopped"
    ;;
  *)
    echo "Usage: $0 {start|stop|restart|status}"
    exit 1
    ;;
esac
exit 0

Paso 2: Coloque el script en /etc/init.d/

sudo cp examplescript /etc/init.d/examplescript

Paso 3: Hágalo ejecutable

sudo chmod +x /etc/init.d/examplescript

Paso 4: Regístrelo en el sistema de niveles de ejecución

sudo update-rc.d examplescript defaults

El argumento defaults registra el script para iniciarse en los niveles de ejecución 2, 3, 4 y 5, y detenerse en los niveles 0, 1 y 6 — el comportamiento estándar para la mayoría de los demonios de servidor.

Paso 5: Verifique el registro

ls -la /etc/rc2.d/ | grep examplescript

Debería ver un enlace simbólico como S01examplescript que apunta de vuelta a /etc/init.d/examplescript.

Error Crítico Común

El error más común con este método es omitir el bloque de encabezado LSB. Sin él, update-rc.d no puede determinar el orden de dependencias, y systemd-sysv-generator puede asignar un orden de ejecución incorrecto en relación con la disponibilidad de red o los montajes del sistema de archivos. Defina siempre las dependencias Required-Start de forma explícita.

Para eliminar el script del inicio automático sin borrarlo:

sudo update-rc.d examplescript disable

Para eliminarlo completamente:

sudo update-rc.d examplescript remove

Método 2: Uso de /etc/rc.local (Shim de Compatibilidad)

Cómo Funciona

/etc/rc.local es un mecanismo heredado que ejecuta un script de shell una vez, después de que todos los servicios estándar del nivel de ejecución multiusuario han iniciado. Es el método de inicio automático más simple posible — sin gestión de servicios, sin declaraciones de dependencias, sin lógica de reinicio. En Ubuntu 18.04 y versiones posteriores, el soporte de rc.local es proporcionado por la unidad systemd rc-local.service, que está deshabilitada por defecto y debe habilitarse explícitamente.

Cuándo Usarlo

Use /etc/rc.local solo para:

  • Comandos de inicialización únicos que no necesitan ser gestionados como servicios
  • Prototipado rápido o pruebas antes de formalizar una unidad systemd
  • Exportaciones simples de variables de entorno o ajustes de parámetros del kernel

No use /etc/rc.local para demonios de larga duración. Debido a que se ejecuta de manera bloqueante y secuencial sin supervisión de procesos, un comando bloqueado en rc.local retrasará o impedirá la finalización de la secuencia de arranque.

Implementación Paso a Paso

Paso 1: Compruebe si /etc/rc.local existe

ls -la /etc/rc.local

Si no existe, créelo:

sudo bash -c 'cat > /etc/rc.local << EOF
#!/bin/bash
exit 0
EOF'
sudo chmod +x /etc/rc.local

Paso 2: Habilite la unidad systemd rc-local (Ubuntu 18.04+)

sudo systemctl enable rc-local
sudo systemctl start rc-local

Paso 3: Agregue su comando antes de exit 0

sudo nano /etc/rc.local

Inserte su comando encima de la línea exit 0:

#!/bin/bash
/usr/local/bin/examplescript.sh >> /var/log/examplescript.log 2>&1 &
exit 0

El & al final es esencial para cualquier comando de larga duración — bifurca el proceso al segundo plano para que rc.local no se bloquee.

Paso 4: Verifique la ejecución

sudo systemctl status rc-local

Error Crítico Común

En Ubuntu 20.04 y 22.04, rc-local.service tiene un tiempo de espera fijo de 30 segundos. Si su script tarda más de 30 segundos en completarse, systemd marcará el servicio como fallido y los comandos posteriores en rc.local no se ejecutarán. Redirija la salida y ponga en segundo plano los procesos de larga duración de forma explícita.

Método 3: Uso de Unidades de Servicio systemd (Recomendado)

Por Qué systemd es el Enfoque Correcto para Producción

systemd no es simplemente un reemplazo de SysVinit — es un gestor completo de sistema y sesión que proporciona resolución de dependencias, inicio paralelo, activación por socket y D-Bus, generación de servicios bajo demanda, supervisión de procesos con reinicio automático, aislamiento de recursos basado en cgroup y agregación de registros estructurados mediante journald. Para cualquier carga de trabajo que se ejecute en un Servidor Dedicado o VPS en producción, las unidades systemd son el único mecanismo apropiado para gestionar scripts de carga automática.

Anatomía de un Archivo de Unidad systemd

Un archivo de unidad .service se divide en tres secciones obligatorias:

  • [Unit]: Metadatos, descripción legible por humanos y declaraciones de dependencias (After=, Requires=, Wants=).
  • [Service]: Parámetros de ejecución — el binario o script a ejecutar, el tipo de servicio, la política de reinicio, las variables de entorno y las opciones de aislamiento de seguridad.
  • [Install]: Define qué objetivo systemd activa esta unidad (WantedBy=multi-user.target es el estándar para los demonios de servidor).

Implementación Paso a Paso

Paso 1: Prepare su script

Asegúrese de que su script sea ejecutable y esté ubicado en una ruta estable:

sudo cp examplescript.sh /usr/local/bin/examplescript.sh
sudo chmod +x /usr/local/bin/examplescript.sh

Paso 2: Cree el archivo de unidad

sudo nano /etc/systemd/system/examplescript.service

Un archivo de unidad de nivel de producción con refuerzo de seguridad:

[Unit]
Description=Example Autoload Script
Documentation=https://your-internal-wiki/examplescript
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/usr/local/bin/examplescript.sh
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5s
StandardOutput=journal
StandardError=journal
SyslogIdentifier=examplescript
User=nobody
Group=nogroup
NoNewPrivileges=true
ProtectSystem=strict
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Paso 3: Recargue el demonio systemd

Después de crear o modificar cualquier archivo de unidad, debe recargar el índice de configuración del demonio:

sudo systemctl daemon-reload

Paso 4: Habilite el servicio para el inicio automático

sudo systemctl enable examplescript.service

Esto crea un enlace simbólico en /etc/systemd/system/multi-user.target.wants/ que apunta a su archivo de unidad.

Paso 5: Inicie el servicio inmediatamente

sudo systemctl start examplescript.service

Paso 6: Verifique el estado y los registros

sudo systemctl status examplescript.service
sudo journalctl -u examplescript.service -f

Comprensión de los Tipos de Servicio systemd

La directiva Type= en la sección [Service] es uno de los parámetros más incomprendidos. Elegir el tipo incorrecto hace que systemd informe incorrectamente la disponibilidad del servicio, lo que lleva a fallos de dependencia.

TipoComportamientoCaso de Uso
simpleEl proceso iniciado por ExecStart es el proceso principal. systemd lo considera listo inmediatamente.Scripts y demonios simples que no se bifurcan
forkingEl proceso se bifurca y el padre termina. systemd rastrea al hijo mediante un archivo PID.Demonios Unix tradicionales (p. ej., Apache con PidFile)
oneshotEl proceso se ejecuta hasta completarse y termina. systemd espera antes de iniciar las unidades dependientes.Tareas de inicialización únicas, scripts de configuración
notifyEl proceso señala su disponibilidad mediante sd_notify().Demonios con integración nativa de systemd
idleLa ejecución se retrasa hasta que todos los trabajos activos sean despachados.Tareas en segundo plano de baja prioridad

Para un script que se ejecuta una vez al arranque y termina, use Type=oneshot con RemainAfterExit=yes para mantener la unidad en estado “activo” después de que el script se complete.

Avanzado: Ordenamiento de Dependencias con After= y Wants=

Un fallo común en producción ocurre cuando un script que requiere conectividad de red se inicia antes de que la pila de red esté completamente inicializada. La cadena de dependencias correcta para scripts dependientes de red es:

After=network-online.target
Wants=network-online.target

Esto es distinto de After=network.target, que solo garantiza que las interfaces de red han sido configuradas — no que estén realmente en línea y accesibles. La dependencia network-online.target requiere que systemd-networkd-wait-online.service o equivalente confirme la conectividad.

Comparación: Los Tres Métodos de un Vistazo

Característica/etc/init.d//etc/rc.localUnidad systemd
Recomendado para producciónNoNo
Soporte de inicio paraleloNoNo
Supervisión de procesos / reinicio automáticoNoNo
Gestión de dependenciasLimitada (encabezados LSB)NingunaCompleta
Registro estructuradoNoNoSí (journald)
Aislamiento de seguridadNoNo
ComplejidadBajaMuy bajaMedia
Compatible con Ubuntu 22.04+Mediante capa de compatibilidadMediante rc-local.serviceNativamente
Adecuado para demonios de larga duraciónParcialmenteNo
Adecuado para tareas de inicialización únicasSí (oneshot)

Errores Comunes y Cómo Evitarlos

Ejecutar scripts como root innecesariamente. Las directivas User= y Group= en los archivos de unidad systemd le permiten reducir privilegios. Un script que solo necesita escribir en /var/log/myapp/ no necesita root — cree un usuario de sistema dedicado y asigne la propiedad del directorio en consecuencia.

No redirigir la salida en rc.local. Sin redirección de salida, cualquier salida de echo o error de los comandos rc.local va a la consola del sistema y se pierde. Agregue siempre >> /var/log/yourscript.log 2>&1.

Usar rutas absolutas de forma inconsistente. Los servicios systemd se ejecutan en un entorno mínimo sin el PATH del usuario. Utilice siempre rutas absolutas para cada binario referenciado en ExecStart, incluidos los intérpretes como /usr/bin/python3 o /bin/bash.

Olvidar daemon-reload después de editar archivos de unidad. systemd almacena en caché el contenido de los archivos de unidad. Si edita un archivo .service y no ejecuta sudo systemctl daemon-reload, systemd continuará usando la configuración antigua.

Colocar archivos de unidad en /lib/systemd/system/ para scripts personalizados. El directorio /lib/systemd/system/ es gestionado por el gestor de paquetes. Los archivos de unidad personalizados pertenecen a /etc/systemd/system/, que tiene precedencia y sobrevive a las actualizaciones de paquetes.

Matriz de Decisión Práctica: Qué Método Usar

Use este marco para seleccionar el método apropiado para su escenario específico:

  • Demonio de larga duración que debe reiniciarse en caso de fallo — unidad systemd con Restart=on-failure
  • Script de configuración único que debe completarse antes de que otros servicios inicien — unidad systemd con Type=oneshot y dependencias Before=
  • Script que requiere que la red esté completamente en línea — unidad systemd con After=network-online.target
  • Comando rápido de una línea para pruebas o prototipado/etc/rc.local (temporalmente)
  • Aplicación heredada entregada con un script de inicio LSB/etc/init.d/ con update-rc.d
  • Cualquier cosa que se ejecute en producción — systemd, siempre

Para los administradores que gestionan múltiples servidores Ubuntu, considere combinar la gestión de unidades systemd con herramientas de gestión de configuración como Ansible, que puede implementar y habilitar archivos .service de forma idempotente en toda su flota. Si necesita un entorno gestionado con acceso root completo para implementar estas configuraciones, el VPS Hosting con un Panel de Control VPS proporciona la flexibilidad para gestionar servicios systemd directamente sin restricciones.

Para los equipos que ejecutan cargas de trabajo intensivas en recursos que requieren scripts de inicio para inicializar controladores GPU, entornos CUDA o servidores de inferencia ML, los entornos de GPU Hosting se benefician especialmente de las cadenas de dependencias After= de systemd, garantizando que los controladores estén completamente cargados antes de que los servicios de aplicación intenten vincularse a los recursos de hardware.

Si sus scripts de carga automática interactúan con configuraciones de servidor web o rutinas de inicialización de bases de datos vinculadas a un entorno de panel de control, las instalaciones de VPS con cPanel requieren especial cuidado — cPanel gestiona su propia capa de supervisión de servicios, y las unidades systemd personalizadas deben definirse para evitar conflictos con los ganchos de gestión de servicios de cPanel.

Lista de Verificación de Puntos Clave Técnicos

Antes de implementar cualquier script de inicio en un servidor Ubuntu, verifique lo siguiente:

  • Ubicación del archivo de unidad: Los scripts personalizados van en /etc/systemd/system/, no en /lib/systemd/system/
  • Bit ejecutable: Confirme con ls -la /path/to/script.sh — el bit x debe estar establecido
  • Rutas absolutas: Cada binario en ExecStart usa una ruta completa; sin dependencia de $PATH
  • Declaraciones de dependencias: After=network-online.target para cualquier script dependiente de red
  • Tipo de servicio: Type=simple para demonios persistentes, Type=oneshot para scripts de ejecución y salida
  • Minimización de privilegios: User=, Group=, NoNewPrivileges=true, ProtectSystem=strict
  • Registro configurado: StandardOutput=journal y StandardError=journal para integración con journald
  • daemon-reload ejecutado: Ejecute siempre sudo systemctl daemon-reload después de crear o editar archivos de unidad
  • Enable vs. start: enable crea el enlace simbólico de inicio automático; start lo ejecuta inmediatamente — ambos son necesarios
  • Probado con journalctl: Confirme la ejecución exitosa con sudo journalctl -u yourservice.service --since "5 minutes ago"

Preguntas Frecuentes

¿Cuál es la diferencia entre systemctl enable y systemctl start?

systemctl enable crea un enlace simbólico que hace que el servicio se inicie automáticamente en el próximo arranque. systemctl start inicia el servicio inmediatamente en la sesión actual. Normalmente necesita ambos comandos al configurar un nuevo servicio por primera vez.

¿Por qué mi servicio systemd falla con “executable not found” aunque el script existe?

Esto casi siempre significa que la ruta ExecStart es incorrecta o que el script carece del bit ejecutable. Verifique con which yourscript y ls -la /path/to/script. También confirme que la primera línea de su script es un shebang válido (#!/bin/bash o #!/usr/bin/env python3), ya que systemd no invoca un shell por defecto para ExecStart.

¿Puedo ejecutar un script al inicio solo una vez, no en cada arranque?

Use Type=oneshot con una directiva ConditionPathExists=!/var/run/myscript.done en la sección [Unit]. El script crea el archivo centinela en la primera ejecución; los arranques posteriores omiten la ejecución porque la condición falla.

¿Sigue siendo compatible /etc/rc.local en Ubuntu 22.04?

Sí, pero está deshabilitado por defecto. Debe habilitar manualmente la unidad rc-local.service con sudo systemctl enable rc-local y asegurarse de que el archivo exista y sea ejecutable. Es compatible como medida de compatibilidad, no como práctica recomendada.

¿Cómo puedo verificar por qué un script de inicio no se ejecutó?

Ejecute sudo journalctl -u yourservice.service -b para ver todas las entradas de registro de esa unidad desde el último arranque. Para fallos de rc.local, compruebe sudo systemctl status rc-local.service y revise /var/log/syslog en busca de entradas con marca de tiempo durante la secuencia de arranque.

15%

Ahorra 15%<\/span> en todos los servicios de hosting

Pon a prueba tus habilidades y obtén Descuento<\/span> en cualquier plan de hosting

Usa el código:

Skills
Comenzar