Sempre me deparo com casos em que preciso que um programa associado ao serviço A seja executado até o fim antes do serviço B. "Depois" não alivia essa coceira. Depois diz
Mais importante ainda, para unidades de serviço, a inicialização é considerada concluída para o propósito de Antes=/Depois= quando todos os seus comandos de inicialização configurados foram invocados e falharam ou relataram sucesso na inicialização.", mas isso não acontece implica que o processo subjacente foi concluído com êxito.
Uma espécie de buraco gritante na funcionalidade IMO. Como posso iniciar o serviço B se ele depende da conclusão bem-sucedida do Serviço A?
Esta resposta responde quase claramente à minha pergunta, mas deixa de fora uma descrição relevante de
Type=oneshot
. Aqui está o texto relevante da documentação do systemd.service .Portanto, pode-se usar serviços oneshot para pedidos determinísticos.
Isso é resolvido inerentemente pelo
Requires=
que você costuma usar quando usaAfter=
; citandoman systemd.unit
:After=
apenas especifica o momento em que sua unidade será iniciada em relação à unidade da qual você depende eRequires=
define que você precisa que a outra unidade seja iniciada com sucesso nesse ponto.O problema com o objetivo é que ele interfere no desligamento. É por isso que você está tendo tanta dificuldade em encontrar uma resposta. Se
shutdown.target
for aumentado, seu serviço será interrompido, mas isso tentará acionar seu serviço de acompanhamento.Se o seu primeiro trabalho for de curta duração, considere combiná-los em um serviço com
Type=simple
e executá-lo comExecStartPre=
. O sistema permaneceráactivating
até que o primeiro trabalho seja concluído e só executará o segundo trabalho se o primeiro for bem-sucedido. Este estilo é útil se o primeiro trabalho precisar fazer uma configuração para o segundo trabalho.Se o segundo trabalho também tiver execução curta, use
Type=oneshot
. Neste caso, ambos os trabalhos podem serExecStart=
.Se o primeiro trabalho não for de curta duração, mas o segundo sim, considere executar o segundo trabalho no
ExecStopPost=
. Mas tenha cuidado porque este comando independentemente de terExecStart=
sido bem-sucedido.$SERVICE_RESULT
Você pode agrupar seu segundo trabalho em um script, executando-o condicionalmente com base no sucesso do primeiro trabalho , verificando$EXIT_CODE
e$EXIT_STATUS
. Este paraíso é particularmente útil se o segundo trabalho for uma tarefa de limpeza.Se ambos os trabalhos forem de longa duração, você precisará ser mais criativo. Uma coisa que você pode fazer é configurar um gatilho com uma
*.path
unidade. Isso acionaria seu serviço irmão quandoPathChanged=
tocado. Para o caminho, eu usaria algo único e prefixado com o%t
especificador para colocar este arquivo/run
:Isto não interferirá no desligamento porque o caminho será interrompido antes de acionar a próxima unidade.