06 · Crear un servicio paso a paso
Vamos a crear un servicio real: uno que ejecuta un script y escribe la fecha en un log. Verás cómo se hace, cómo se depura y cómo se habilita al arranque.
Paso 1: preparar el script
Crearemos un script simple. Puede ser cualquier cosa: un backup, un mensaje, un servidor Python.
mkdir -p ~/scripts
nano ~/scripts/saludo.sh
Contenido de saludo.sh:
#!/bin/bash
echo "$(date): Hola desde el servicio de prueba" >> /home/tu_usuario/scripts/saludo.log
Guarda (Ctrl+O, Enter, Ctrl+X) y dale permisos de ejecución:
chmod +x ~/scripts/saludo.sh
~/scripts/saludo.sh # prueba manual
cat ~/scripts/saludo.log # verifica que escribió
Paso 2: crear el archivo de unidad
sudo nano /etc/systemd/system/saludo.service
Contenido, con cada línea explicada:
[Unit]
Description=Servicio de prueba que escribe un saludo en un log
After=network.target
[Service]
Type=oneshot
ExecStart=/home/tu_usuario/scripts/saludo.sh
User=tu_usuario
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Paso 3: entender cada directiva
| Directiva | Qué hace |
|---|---|
[Unit] | Metadatos y dependencias |
Description | Texto que verás en systemctl status |
After=network.target | Arranca después de que la red esté lista |
[Service] | Cómo se ejecuta |
Type=oneshot | El script termina y el servicio se considera "hecho". Para procesos que se quedan corriendo, usa simple. |
ExecStart | Comando absoluto a ejecutar |
User | Usuario con el que se ejecuta (buena práctica, no usar root) |
RemainAfterExit=yes | Solo para oneshot: systemd lo marca como activo aunque el script ya haya terminado |
[Install] | Cómo se integra al arranque |
WantedBy=multi-user.target | Se arranca cuando el sistema entra en modo multiusuario (arranque normal). Es lo que necesita enable. |
Type=simple (para servidores, procesos que se quedan corriendo) · Type=oneshot (para scripts que terminan) · Type=forking (para servicios clásicos que se bifurcan) · Type=notify (para los que avisan a systemd cuando están listos).
Paso 4: recargar y habilitar
sudo systemctl daemon-reload
sudo systemctl enable --now saludo.service
Si olvidas
daemon-reload, systemd no verá el archivo nuevo. Es el error más común de principiantes.
Paso 5: verificar
systemctl status saludo.service
Deberías ver Active: active (exited) o active (running). Si ves failed, revisa:
journalctl -u saludo.service -n 50
Los errores típicos son: ruta mal escrita en ExecStart, script sin chmod +x, o usuario inexistente en User=.
Paso 6: probar el ciclo completo
sudo systemctl stop saludo.service # detener
sudo systemctl start saludo.service # arrancar
sudo systemctl restart saludo.service # reiniciar
sudo systemctl disable saludo.service # quitar del auto-arranque
sudo systemctl enable saludo.service # volver a poner
Variante: servicio de usuario (sin sudo)
Para cosas personales es más limpio usar servicios de usuario. Se guardan en ~/.config/systemd/user/ y no necesitan permisos de root.
mkdir -p ~/.config/systemd/user
nano ~/.config/systemd/user/mi-script.service
[Unit]
Description=Mi script personal
[Service]
Type=oneshot
ExecStart=/home/tu_usuario/scripts/saludo.sh
[Install]
WantedBy=default.target
Gestión (sin sudo):
systemctl --user daemon-reload
systemctl --user enable --now mi-script.service
systemctl --user status mi-script.service
Errores frecuentes y su solución
Error en status | Causa | Solución |
|---|---|---|
status=203/EXEC | No encuentra el ejecutable o no es ejecutable | Verifica ruta absoluta y chmod +x |
status=200/CHDIR | El WorkingDirectory no existe | Corrige la ruta o quítala |
status=1/FAILURE | El script devolvió error | Ejecuta el script a mano y mira qué falla |
Permission denied | El User= no tiene permiso al archivo | Ajusta permisos o dueño |
| Cambios no se aplican | Falta daemon-reload | sudo systemctl daemon-reload |
🧪 Práctica sugerida
- Crea
~/scripts/saludo.shy pruébalo a mano. - Crea
saludo.service, ejecutadaemon-reloadyenable --now. - Comprueba
systemctl status saludoy el log. - Reinicia el equipo y verifica con
systemctl status saludoque arrancó solo.