Qual é o substituto correto para rc.local no systemd em vez de recriar rc.local

25

Não consigo encontrar a maneira correta de executar alguns scripts locais (ou comandos muito locais) no systemd, já sei que não devo criar um serviço (no systemd uma unidade) para esse tipo de script (ou devo?) ....

A solução alternativa que encontrei é criar o rc.local e conceder permissões de execução.

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

Por exemplo, se eu receber um servidor legado com um rc.local simples configurado por você, vou saber o que você fez e quanto vai doer para atualizar ou instalar algo novo na distribuição, pois o rc.local foi respeitado por fontes externas. pacotes, mas por outro lado, se eu instalar um servidor e criar uma unidade systemd ou dois ou três (ou até serviços sysvinit), apenas para executar uma tarefa simples, isso pode às vezes dificultar sua vida e muito mais do que isso minhas unidades algum dia os nomes podem entrar em conflito com os nomes dos novos serviços criados pelo desenvolvimento da distribuição e talvez instalados em uma atualização, causando problemas para meus scripts!

Vejo outra pergunta perguntando onde está o rc.local e a resposta foi criá-lo e conceder permissões de execução. Acho que minha pergunta não é realmente uma duplicata , porque não quero saber onde ela está - acredite, só quero para aceitar que está obsoleto , mas não consigo encontrar a maneira correta de fazer esse tipo de coisa, devo criar uma unidade apenas para coisas simples como essa?

Luciano Andress Martini
fonte
4
systemd "a única jogada vencedora é não jogar"; Como alternativa, dependendo do que você deseja, você pode criar uma unidade systemd. Eu provavelmente usaria o rc.local por enquanto e me preocupo com isso quando ele desaparecer.
Rui F Ribeiro
Então você acha que a maneira oficial é criar uma unidade como um serviço? Por favor, poste como resposta como fazer isso.
Luciano Andress Martini
1
Quando tentei o Ubuntu, criei uma Unidade para ter um persistente ssh-agent em cache na minha área de trabalho enquanto não reinicializei e outra para outra coisa que não me lembro; você também pode criar um apontador para /etc/rc.local, mas parece que o sistema está fazendo isso por si mesmo por enquanto .... Gostaria de rc.local por enquanto e, se for interrompido, crie um apontador para um arquivo falso. /etc/rc.local então.
Rui F Ribeiro
É provável que isso interrompa as documentações como se algum livro dissesse que você deve colocar algo em /etc/rc.local e tente atualizar esses documentos, dizendo, por exemplo, que rc.local deve ser marcado como executável, quando ficar totalmente obsoleto. a documentação está quebrada, mas se você disser que deve criar a unidade para apontar para /etc/rc.local, isso interrompe a documentação porque o systemd está em conflito com a sua unidade. Acredito que, se você estiver certo, eles provavelmente não decidiram se foi preterido ou não, porque ainda não têm um substituto ... quando decidem que toda a documentação será quebrada novamente.
Luciano Andress Martini
Que tipo de script você precisa executar? O Systemd possui muitos tipos de unidades. "Serviço" é apenas um dos muitos tipos de unidades . Por exemplo, monte unidades, unidades de montagem automática, unidades de timer, unidades de destino. Um deles poderia resolver seu problema?
andcoz

Respostas:

17

Como salientado em outro lugar, torna-se moderadamente impuro para usar rc-local.servicesob systemd.

  1. É teoricamente possível que sua distribuição não a habilite. (Eu acho que isso não é comum, por exemplo, porque desabilitar a mesma opção de compilação também remove poweroff/ rebootcomanda que muitas pessoas usam).
  2. A semântica não é totalmente clara. O Systemd define rc-local.serviceuma maneira, mas o Debian fornece um arquivo drop-in que altera pelo menos uma configuração importante.

rc-local.servicemuitas vezes pode funcionar bem. Se você está preocupado com o exposto, tudo o que você precisa fazer é fazer sua própria cópia! Aqui está a mágica:

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

[Install]
WantedBy=multi-user.target

Eu não acho que você precise entender todos os detalhes [*], mas há duas coisas que você precisa saber aqui.

  1. Você precisa habilitar isso com systemctl enable my-startup.service.

  2. Se o seu script depende de qualquer outro serviço, inclusive network-online.target, você deve declará-lo. Por exemplo, adicione uma [Unit]seção, com as linhas Wants=network-online.targete After=network-online.target.

    Você não precisa se preocupar com dependências nos serviços de "inicialização antecipada" - especificamente, serviços que já foram solicitados anteriormente basic.target. Serviços como my-startup.servicesão pedidos automaticamente depois basic.target, a menos que sejam definidos DefaultDependencies=no.

    Se você não tiver certeza se uma de suas dependências é um serviço de "inicialização antecipada", uma abordagem é listar os serviços encomendados antes basic.target, executando systemctl list-dependencies --after basic.target. (Observe que --afternão --before).

Há algumas considerações que eu acho que também se aplicavam ao pré-systemd rc.local:

  1. Você precisa garantir que seus comandos não estejam em conflito com outro programa que tenta controlar a mesma coisa.
  2. É melhor não iniciar programas de longa duração, também conhecidos como daemons rc.local.

[*] Eu usei Type=oneshot+ RemainAfterExit=yesporque faz mais sentido para a maioria dos scripts únicos. Ele formaliza que você executará uma série de comandos, que my-startupserão mostrados como "ativos" após a conclusão e que você não iniciará um daemon.

sourcejedi
fonte
Bem, existe algum tipo de local "local" para a criação de serviços ou trechos, ou o que for - ou posso confiar que é local e não deve ser alterado? se eu desenvolver meus próprios daemons? Como eu não quero alterar a originalidade do sistema, então, quando instalo o apt-get, não quero ver meu sistema pegando fogo por causa de um script substituído ou algo parecido, por exemplo. Eu só quero confiar que o daemon será iniciado apenas uma vez, sem fazer outras coisas loucas que eu temo ... como tentar reiniciá-lo como infinito se estiver quebrado, etc ...
Luciano Andress Martini
1
@LucianoAndressMartini, se você está perguntando qual é o caminho certo para iniciar um daemon, deve realmente definir um serviço individual para ele. Pode ser uma .serviceunidade de sistema nativa ou, se você realmente deseja escrever um script de inicialização LSB, pode fazê-lo. Eu não queria recomendar a instalação de vários daemons rc-local.serviceou equivalente, acho que provavelmente funciona, mas parece muito melhor se você puder reiniciar o daemon individual com systemctl restart my-daemonqualquer outra coisa. Pretende-se que você coloque seus serviços locais /etc/systemd/system.
precisa saber é o seguinte
1
@LucianoAndressMartini, você deve evitar usar o mesmo nome que qualquer outro serviço - assim como no sysvinit. Em situações semelhantes que eu às vezes começou meus nomes com local-...
sourcejedi
1
Obrigado!!! Salvo após meio dia. Esses detalhes foram críticos para mim: Tipo = oneshot, RemainAfterExit = yes, Quer = network-online.target, After = network-online.target. Apenas implantando uma compilação do apache e configurando o IP estático para 192.168.1.80, para que o roteador possa direcionar o tráfego para lá. Deve ser trivial. É irritante no Debian9. Quase nenhum conselho on-line, exceto "apt-get apache", "systemctl start apache" ou instruções com init.d, nenhum dos quais se aplica ao Apache de origem no Debian9.
quer
1
@MichaelsonBritt É melhor não iniciar programas de longa duração, também conhecidos como daemons, no rc.local. Eu usei Type=oneshot... formaliza que ... você não iniciará um daemon. Se você quiser informações sobre como iniciar um daemon, faça uma nova pergunta.
sourcejedi 8/06
15

Esqueça rc.local.

Como eu disse sobre CentOS 7 e sobre o Debian 8 e sobre o Ubuntu 15 :

Você está usando um sistema operacional systemd + Linux. /etc/rc.localé um mecanismo de compatibilidade com versões anteriores duplas no systemd, porque é um mecanismo de compatibilidade com versões anteriores de um mecanismo que por si só era um mecanismo de compatibilidade no rcclone van Smoorenburg System 5 .

Usar /etc/rc.localpode dar terrivelmente errado. As pessoas ficaram surpresas com o fato de o systemd não funcionar rc.localda mesma maneira, no mesmo local do bootstrap, como estão acostumados. (Ou, erroneamente, espera: na verdade, ele não foi executado por último no sistema antigo, como o manual do OpenBSD ainda aponta.) Outros se surpreenderam com o fato de que o que eles criaram rc.localesperando as velhas formas de fazer as coisas é então completamente desfeita pelos gostos de novas udevregras, o NetworkManager, systemd-logind, systemd-resolved, ou vários "kit" s.

Como exemplificado por " Por que o` init 0` resulta em "Excesso de Argumentos" na instalação do Arch? ", Alguns sistemas operacionais já fornecem systemd sem os recursos de compatibilidade com versões anteriores , como o systemd-rc-local-generatorgerador . Enquanto o Debian ainda mantém os recursos de compatibilidade com versões anteriores , o Arch Linux constrói o systemd com eles desativados . Assim, no Arch e nos sistemas operacionais como ele esperam /etc/rc.local ser totalmente ignorados .

Esqueça rc.local. Não é o caminho a percorrer. Você tem um sistema operacional systemd + Linux. Portanto, faça uma unidade de serviço do sistema adequada e não comece a partir de um ponto que esteja a dois níveis de compatibilidade com versões anteriores. (No Ubuntu e no Fedora, ele é removido três vezes, o rcclone van Smoorenburg System 5 que se seguiu rc.localfoi substituído por duas vezes , há mais de uma década, primeiro pelo iniciante e depois pelo systemd.)

Lembre-se também da primeira regra para migrar para o systemd .

Essa nem é uma idéia nova, específica do systemd. Nos rcsistemas van Smoorenburg e Upstart, a coisa a fazer era criar um rcscript van Smoorenburg ou arquivo de trabalho Upstart adequado, em vez de usá-lo rc.local. Até o manual do FreeBSD observa que hoje em dia se cria um rcscript Mewburn adequado em vez de usar /etc/rc.local. Mewburn rcfoi introduzido pelo NetBSD 1.5 em 2000.

/etc/rc.localdata da época da sétima edição Unix e antes. Foi substituído por /etc/inittabum nível de execução rcno AT&T Unix System 3 (com um pouco diferente /etc/inittabno AT&T Unix System 5) em 1983 . Até isso agora é história.

Crie definições de serviço nativas apropriadas para o seu sistema de gerenciamento de serviços, seja um pacote configurável para os conjuntos de ferramentas nosh service-managere system-control, um /etc/rc.d/script para Mewburn rc, um arquivo de unidade de serviço para systemd, um arquivo de tarefa para Upstart, um diretório de serviço para runit / s6 / daemontools -core, ou mesmo um /etc/init.d/script para van Smoorenburg rc.

No systemd, esses arquivos de unidades de serviço adicionadas pelo administrador entram /etc/systemd/system/normalmente (ou /usr/local/lib/systemd/system/raramente). Com o nosh service manager, /var/local/sv/é um local convencional para pacotes de serviços locais. Mewburn rcnos usos do FreeBSD /usr/local/etc/rc.d/. Arquivos de unidades de serviço empacotados e pacotes de serviços, se você os estiver criando, vão para lugares diferentes.

Leitura adicional

JdeBP
fonte
2
@LucianoAndressMartini Uma pergunta melhor seria como lidar com um trecho específico de rc.local em um serviço systemd. Então, se você tem um trecho específico em mente (você menciona instruções da documentação de alguns softwares), talvez poste uma pergunta sobre esse? Existem certas regras gerais que podem ser usadas para a conversão, mas você aproveita ao explorar os recursos do software que está executando (como executar em primeiro plano, não tentar daemonizar etc.), perguntando sobre um caso específico pode ser útil.
filbranden
4
Você quer saber se ele sobreviveu à depreciação desde 1983, talvez tenha algo a seu favor?
dan carter
4
Essa resposta é pregadora e falha em responder apenas à pergunta simples "que coisa trivial devo fazer". Pode conter informações e fornecer inúmeras referências, mas derrota o objetivo da troca de pilhas.
gps
Eu trago isso (o final do rc.local), junto com a resolução de problemas de DNS, como razões pelas quais o linux não está evoluindo, mas realmente chegando a ser um código espaguete cada vez mais, o systemd se tornou uma caixa preta para muitos. Se um usuário ou administrador quiser colocar algo em rc.local e não puder mais, não é útil forçá-lo a fazer primeiro cursos systemd ou qualquer outra coisa que você pregue para obter o mesmo resultado final em dias, em vez de minutos. Obviamente, idiotas podem fazer coisas estúpidas com tudo que funciona bem e é fácil de trabalhar, isso nunca é um argumento válido para acabar com isso.
Julius
2

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

Crie /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

Então:

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

Verificar com:

sudo systemctl start rc-local.service
sudo systemctl status rc-local.service
Ole Tange
fonte
O fornecido pelo sistema é usado StandardOutput=journal+console(o console é equivalente a tty no seu exemplo), o que parece ser muito mais útil para solucionar problemas. Também o suporte para SysVStartPriority=foi removido em algum momento. Talvez você possa comentar o quão importante SysVStartPriority=é ou removê-lo. Além disso, é uma resposta decente.
sourcejedi 4/11