¿Cuál es el sustituto correcto de rc.local en systemd en lugar de volver a crear rc.local?

25

No puedo encontrar la forma correcta de ejecutar algunos scripts locales (o comandos muy locales) en systemd, ya sé que no debo crear un servicio (en systemd una unidad) para este tipo de scripts (¿o debo hacerlo?) ...

La solución que encontré es crear rc.local y darle permisos de ejecución.

printf '#!/bin/bash \n\nexit 0' >/etc/rc.local 
chmod +x /etc/rc.local

Por ejemplo, si obtengo un servidor heredado con un simple rc.local configurado por usted, sabré qué hizo y cuánto me va a doler actualizar o instalar algo nuevo en la distribución, ya que rc.local fue respetado por externos paquetes, pero por otro lado si instalo un servidor y creo una unidad systemd o dos o tres (o incluso servicios sysvinit), solo por hacer una tarea simple, esto a veces puede hacer su vida más difícil, y mucho más que esto mis unidades algún día, los nombres pueden entrar en conflicto con los nombres de los nuevos servicios creados por el desarrollo de la distribución, y tal vez instalados en una actualización, causando problemas a mis scripts.

Veo otra pregunta sobre dónde está rc.local y la respuesta fue crearlo y otorgar permisos de ejecución, creo que mi pregunta realmente no es un duplicado , porque no quiero saber dónde está, créeme, solo quiero para aceptar que está en desuso , pero no puedo encontrar la forma correcta de hacer este tipo de cosas, ¿realmente debería crear una unidad para algo así de simple?

Luciano Andress Martini
fuente
44
systemd "el único movimiento ganador es no jugar"; alternativamente, dependiendo de lo que desee, puede crear una Unidad systemd. Probablemente usaría rc.local por ahora, y me preocuparía cuando desaparezca.
Rui F Ribeiro
¿Entonces crees que la forma oficial es crear una unidad como un servicio? Por favor, publique como respuesta cómo hacerlo.
Luciano Andress Martini
1
Cuando probé Ubuntu, creé una Unidad para tener un caché de ssh-agent persistente en mi escritorio mientras no reiniciaba y otra para algo más que no puedo recordar; también puede crear uno apuntando a /etc/rc.local pero parece que el sistema lo está haciendo por usted mismo por ahora ... De momento, rc.local, y si se descontinúa, cree uno apuntando a un falso /etc/rc.local entonces.
Rui F Ribeiro
Es probable que esto rompa las documentaciones como si algún libro dijera que debe poner algo en /etc/rc.local e intente actualizar estos documentos, diciendo, por ejemplo, que rc.local debe estar marcado como ejecutable, cuando se vuelve totalmente obsoleto la documentación está rota, pero si dice que debe crear una unidad para apuntar a /etc/rc.local, esto rompe la documentación porque systemd está en conflicto con su unidad. Creo que si tiene razón, probablemente no decidieron si está en desuso o no, porque todavía no tienen un sustituto ... cuando deciden que toda la documentación se volverá a romper.
Luciano Andress Martini
¿Qué tipo de script necesitas ejecutar? Systemd tiene muchos tipos de unidades. "Servicio" es solo uno de los muchos tipos de unidades . Por ejemplo, unidades de montaje, unidades de montaje automático, unidades de temporizador, unidades objetivo. ¿Podría uno de ellos resolver su problema?
andcoz

Respuestas:

17

Como se señaló en otra parte, se vuelve moderadamente impuro usar rc-local.servicedebajo systemd.

  1. Es teóricamente posible que su distribución no lo habilite. (Creo que esto no es común, por ejemplo, porque deshabilitar la misma opción de compilación también elimina poweroff/ rebootcomandos que mucha gente usa).
  2. La semántica no está del todo clara. Systemd define rc-local.serviceuna forma, pero Debian proporciona un archivo desplegable que modifica al menos una configuración importante.

rc-local.serviceA menudo puede funcionar bien. Si le preocupa lo anterior, ¡todo lo que necesita hacer es hacer su propia copia! Aquí está la magia:

# /etc/systemd/system/my-startup.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/libexec/my-startup-script

[Install]
WantedBy=multi-user.target

No creo que necesite comprender cada detalle [*], pero hay dos cosas que debe saber aquí.

  1. Necesita habilitar esto con systemctl enable my-startup.service.

  2. Si su script tiene una dependencia de cualquier otro servicio, incluido network-online.target, debe declararlo. Por ejemplo, agregue una [Unit]sección, con las líneas Wants=network-online.targety After=network-online.target.

    No necesita preocuparse por las dependencias de los servicios de "arranque temprano", específicamente, los servicios que ya se ordenaron anteriormente basic.target. Los servicios como my-startup.servicese ordenan automáticamente después basic.target, a menos que se establezcan DefaultDependencies=no.

    Si no está seguro de si una de sus dependencias es un servicio de "arranque temprano", un enfoque es enumerar los servicios que se ordenaron antes basic.target, ejecutándose systemctl list-dependencies --after basic.target. (Tenga en cuenta que --afterno --before).

Hay algunas consideraciones que creo que también se aplicaron a pre-systemd rc.local:

  1. Debe asegurarse de que sus comandos no entren en conflicto con otro programa que intente controlar lo mismo.
  2. Es mejor no iniciar programas de larga duración, también conocidos como daemons rc.local.

[*] Utilicé Type=oneshot+ RemainAfterExit=yesporque tiene más sentido para la mayoría de los scripts de una sola vez. Se formaliza que ejecutará una serie de comandos, que my-startupse mostrarán como "activos" una vez que se hayan completado, y que no iniciará un demonio.

sourcejedi
fuente
Bueno, hay algún tipo de lugar "local" para crear servicios o fragmentos, o lo que sea, ¿o puedo confiar en que esto es local y no debería modificarse? si desarrollo mis propios demonios? Debido a que no quiero alterar la originalidad del sistema, por lo tanto, cuando instalo algunos apt-get, no quiero ver mi sistema en llamas debido a un script reemplazado, o algo así, por ejemplo. Solo quiero confiar en que el demonio solo se iniciará una vez, sin hacer ninguna locura adicional que me temo ... como intentar reiniciarlo como infinito si está roto, etc.
Luciano Andress Martini
1
@LucianoAndressMartini si está preguntando cuál es la forma correcta de iniciar un demonio, realmente debería definir un servicio individual para él. Puede ser una .serviceunidad de sistema nativa , o si realmente desea escribir un script de inicio LSB, puede hacerlo en su lugar. No quería recomendar poner varios demonios rc-local.serviceo equivalentes, creo que probablemente funcione, pero parece mucho mejor si puedes reiniciar el demonio individual con systemctl restart my-daemoncualquier otra cosa. Está destinado a poner sus servicios locales /etc/systemd/system.
sourcejedi
1
@LucianoAndressMartini debe evitar usar el mismo nombre que cualquier otro servicio, al igual que en sysvinit. En situaciones similares, a veces comencé mis nombres con local-...
sourcejedi
1
¡¡¡Gracias!!! Guardado después de medio día. Estos detalles fueron críticos para mí: Type = oneshot, RemainAfterExit = yes, wants = network-online.target, After = network-online.target. Simplemente implementando una compilación de apache y configurando la IP estática en 192.168.1.80, para que el enrutador pueda dirigir el tráfico allí. Debería ser trivial. Es molesto en Debian9. Casi ningún consejo en línea, excepto "apt-get apache", "systemctl start apache" o instrucciones con init.d, ninguno de los cuales se aplica a Apache construido en origen en Debian9.
MichaelsonBritt
1
@MichaelsonBritt Es mejor no iniciar programas de larga duración, también conocidos como demonios, de rc.local. Solía Type=oneshot... formaliza que ... no iniciarás un demonio. Si desea información sobre cómo iniciar un demonio, haga una nueva pregunta.
sourcejedi
15

Olvidarse de rc.local.

Como dije sobre CentOS 7 y sobre Debian 8 y sobre Ubuntu 15 :

Estás utilizando un sistema operativo systemd + Linux. /etc/rc.locales un doble mecanismo de compatibilidad con versiones anteriores en systemd, porque es un mecanismo de compatibilidad con versiones anteriores para un mecanismo que era en sí mismo un mecanismo de compatibilidad en el clon del Sistema 5 de Van Smoorenburg rc.

Usar /etc/rc.localpuede salir terriblemente mal. La gente se ha sorprendido por el hecho de que systemd no se ejecuta rc.localde la misma manera, en el mismo lugar en el arranque, como solía hacerlo. (O erróneamente espere: de hecho, no se ejecutó por última vez en el sistema anterior, como todavía señala el manual de OpenBSD). Otros se han sorprendido por el hecho de que lo que establecieron al rc.localesperar las viejas formas de hacer las cosas, es entonces completamente deshecho por los gustos de las nuevas udevnormas, NetworkManager, systemd-logind, systemd-resolved, o varios "kit" s.

Como se ejemplifica en " ¿Por qué` init 0` resulta en "Argumentos excesivos" en la instalación de Arch? ", Algunos sistemas operativos ya proporcionan systemd sin las características de compatibilidad con versiones anteriores , como el systemd-rc-local-generatorgenerador . Mientras Debian aún conserva las características de compatibilidad con versiones anteriores , Arch Linux construye systemd con ellas desactivadas . Entonces, en Arch y sistemas operativos como este, se espera /etc/rc.local que se ignore por completo .

Olvidarse de rc.local. No es el camino a seguir. Tiene un sistema operativo systemd + Linux. Por lo tanto, cree una unidad de servicio systemd adecuada y no comience desde un punto que esté a dos niveles de compatibilidad con versiones anteriores. (En Ubuntu y Fedora, se eliminó tres veces, el clon de Van Smoorenburg System 5 rcque siguió rc.localluego fue reemplazado dos veces , hace más de una década, primero por advenedizo y luego por systemd).

Recuerde también la primera regla para migrar a systemd .

Esto ni siquiera es una idea nueva que sea específica de systemd. En los sistemas van Smoorenburg rcy Upstart, lo que había que hacer era crear un rcscript de van Smoorenburg o un archivo de trabajo Upstart adecuado en lugar de usarlos rc.local. Incluso el manual de FreeBSD señala que hoy en día uno crea un rcscript Mewburn adecuado en lugar de usarlo /etc/rc.local. Mewburn rcfue presentado por NetBSD 1.5 en 2000.

/etc/rc.localdata de la época de la Séptima Edición Unix y anteriores. Fue reemplazado /etc/inittaby basado rcen un nivel de ejecución en AT&T Unix System 3 (con un poco diferente /etc/inittaben AT&T Unix System 5) en 1983 . Incluso eso es ahora historia.

Cree definiciones de servicio nativas adecuadas para su sistema de gestión de servicios, ya sea un paquete de servicios para el conjunto de herramientas nosh service-managery system-control, un /etc/rc.d/script para Mewburn rc, un archivo de unidad de servicio para systemd, un archivo de trabajo para Upstart, un directorio de servicio para runit / s6 / daemontools -encore, o incluso un /etc/init.d/guión para van Smoorenburg rc.

En systemd, estos archivos de unidad de servicio agregados por el administrador entran /etc/systemd/system/generalmente (o /usr/local/lib/systemd/system/raramente). Con el administrador de servicios nosh, /var/local/sv/es un lugar convencional para paquetes de servicios locales. Mewburn rcen los usos de FreeBSD /usr/local/etc/rc.d/. Sin embargo, los archivos de la unidad de servicio empaquetada y los paquetes de servicio, si los está haciendo, van a diferentes lugares.

Otras lecturas

JdeBP
fuente
2
@LucianoAndressMartini Una mejor pregunta sería cómo manejar un fragmento específico de rc.local en un servicio systemd. Entonces, si tiene un fragmento específico en mente (menciona las instrucciones de la documentación de algún software), ¿puede publicar una pregunta sobre ese? Existen ciertas reglas generales que se pueden usar para la conversión, pero se aprovecha más al aprovechar las funciones del software que está ejecutando (como ejecutar en primer plano, no tratar de demonizar, etc.) por lo que pregunta sobre un caso específico Podría ser útil.
filbranden
44
Tienes que preguntarte si ha sobrevivido a la degradación desde 1983, ¿tal vez tiene algo a su favor?
Dan Carter
44
Esta respuesta es predicativa y en realidad no responde a la simple pregunta "¿qué cosa trivial debo hacer en su lugar?". Puede contener información y proporcionar toneladas de referencias, pero anula el propósito de stackexchange.
GPS
Traigo esto (el final de rc.local), junto con la resolución de problemas de dns, como razones por las que Linux no está evolucionando, pero en realidad se está convirtiendo en un código de espagueti cada vez más, systemd se ha convertido en una caja negra para muchos. Si un usuario o administrador quiere poner algo en rc.local y ya no puede, no es útil obligarlo a hacer primero los cursos systemd o cualquier otra cosa que predique para lograr el mismo resultado final en días, en lugar de minutos. Por supuesto, los idiotas pueden hacer cosas estúpidas con todo lo que funciona bien y es fácil trabajar con él, eso nunca es un argumento válido para terminarlo.
Julio
2

Resumen de https://www.linuxbabe.com/linux-server/how-to-enable-etcrc-local-with-systemd

Cree /etc/systemd/system/rc-local.service:

# /etc/systemd/system/rc-local.service
[Unit]
 Description=/etc/rc.local Compatibility
 ConditionPathExists=/etc/rc.local

[Service]
 Type=forking
 ExecStart=/etc/rc.local start
 TimeoutSec=0
 StandardOutput=tty
 RemainAfterExit=yes
 SysVStartPriority=99

[Install]
 WantedBy=multi-user.target

Luego:

sudo touch /etc/rc.local
sudo chmod +x /etc/rc.local
sudo systemctl enable rc-local

Verifícalo con:

sudo systemctl start rc-local.service
sudo systemctl status rc-local.service
Ole Tange
fuente
El sistema provisto por systemd StandardOutput=journal+console(la consola es equivalente a tty en su ejemplo), lo que parece que sería mucho más útil para la resolución de problemas. También SysVStartPriority=se ha eliminado el soporte para en algún momento. Tal vez podrías comentar lo importante que SysVStartPriority=es o eliminarlo. Aparte de eso, es una respuesta decente.
sourcejedi