Como posso executar um comando quando uma unidade de serviço do systemd está sendo desativada?

Como posso executar um comando quando uma unidade de serviço do systemd está sendo desativada?

Eu tenho a seguinte unidade de serviço systemd para definir os limites de bateria do meu laptop:

[Unit]
Description=Set Battery Charge Thresholds

[Service]
Type=oneshot
ExecStart=/usr/bin/tpacpi-bat -s --start 1 30
ExecStart=/usr/bin/tpacpi-bat -s --stop 1 85
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

O que eu gostaria é de uma maneira de executar comandos quando eu desabilitar a unidade de serviço (para que eu possa definir convenientemente os limites de volta aos padrões). Isso é possível?

Responder1

Dê uma olhada ExecStopouExecStopPost

ExecStop

Comandos a serem executados para parar o serviço iniciado via ExecStart=. Este argumento utiliza múltiplas linhas de comando, seguindo o mesmo esquema descrito para ExecStart= acima. O uso desta configuração é opcional. Depois que os comandos configurados nesta opção forem executados, todos os processos restantes para um serviço serão finalizados de acordo com a configuração KillMode= (veja systemd.kill(5)). Se esta opção não for especificada, o processo é finalizado enviando o sinal especificado em KillSignal= quando a parada do serviço for solicitada. A substituição de especificador e variável de ambiente é suportada (incluindo $MAINPID, veja acima).

...

Recomenda-se usar essa configuração para comandos que se comunicam com o serviço que solicita o encerramento limpo. Quando os comandos especificados com esta opção são executados, deve-se presumir que o serviço ainda está totalmente ativo e é capaz de reagir corretamente a todos os comandos. Para etapas de limpeza post-mortem, use ExecStopPost=.

ExecStopPost

Comandos adicionais que são executados após a interrupção do serviço. Isso inclui casos em que os comandos configurados em ExecStop= foram usados, em que o serviço não possui nenhum ExecStop= definido ou em que o serviço foi encerrado inesperadamente. Este argumento utiliza múltiplas linhas de comando, seguindo o mesmo esquema descrito para ExecStart=. O uso dessas configurações é opcional. A substituição de especificador e variável de ambiente é suportada. Observe que – diferentemente de ExecStop= – os comandos especificados com esta configuração são invocados quando um serviço falha ao inicializar corretamente e é encerrado novamente.

Recomenda-se usar esta configuração para operações de limpeza que devem ser executadas mesmo quando o serviço não foi inicializado corretamente. Os comandos configurados com esta configuração precisam ser capazes de operar mesmo se o serviço falhar na inicialização no meio do caminho e deixar dados inicializados de forma incompleta. Como os processos do serviço já foram finalizados quando os comandos especificados com esta configuração são executados, eles não devem tentar se comunicar com eles.

Observe que todos os comandos configurados com esta configuração são invocados com o código de resultado do serviço, bem como o código de saída e status do processo principal, definido nas variáveis ​​de ambiente $SERVICE_RESULT, $EXIT_CODE e $EXIT_STATUS, consulte systemd.exec (5) para detalhes.

Ambos podem ser usados ​​para executar comandos quando o serviço é interrompido.

As principais diferenças entre os dois:

  • ExecStopé executado enquanto o processo principal ainda está em execução e só será executado quando o serviço for interrompido após a execução normal (ou seja, todos os serviços ExecStartdevem ExecStartPreser bem-sucedidos e qualquer um Conditions... também deve passar.

  • ExecStopPosté executado mesmo se o "serviço tiver sido encerrado inesperadamente", o que cobre falhas. A maior vantagem disso é quando você tem vários ExecStarts, se um deles for bem-sucedido e o outro falhar, ExecStopPostpode ser usado para tentar limpar o sucesso parcial.

informação relacionada