Systemd: Como executar o script apenas no desligamento (não na reinicialização)

Systemd: Como executar o script apenas no desligamento (não na reinicialização)

Há muitas soluções aqui para executar um script no desligamento/reinicialização, mas quero que meu script seja executado apenas no desligamento.

Tentei colocar meu script em /usr/lib/systemd/systemd-shutdown e verificar o parâmetro $1, como vistoaqui, mas não funciona.

Alguma ideia ?

sistema: archlinux com gnome-shell

$systemctl --version                                                                                                                                                                                 
systemd 229
+PAM -AUDIT -SELINUX -IMA -APPARMOR +SMACK -SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN

Responder1

Finalmente descobri como fazer isso.

É um pensamento um pouco hackeado, mas funciona.

Eu usei alguma parte deste tópico:https://stackoverflow.com/questions/25166085/how-can-a-systemd-controlled-service-distinguish-between-shutdown-and-reboot

e este tópico: Como executar um script com o systemd logo antes do desligamento?

Eu criei este serviço/etc/systemd/system/shutdown_screen.service

[Unit]
Description=runs only upon shutdown
Conflicts=reboot.target
After=network.target

[Service]
Type=oneshot
ExecStart=/bin/true
ExecStop=/bin/bash /usr/local/bin/shutdown_screen
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Que será executado em shutdown/reboot/halt/whatever. (não se esqueça de habilitá-lo)

E no meu script /usr/local/bin/shutdown_screen coloquei o seguinte:

#!/bin/bash
# send a shutdown message only at shutdown (not at reboot)    
/usr/bin/systemctl list-jobs | egrep -q 'reboot.target.*start' || echo "shutdown" | nc 192.168.0.180 4243 -w 1

O que enviará uma mensagem de desligamento para meu arduino, que desligará minha tela.

Responder2

De acordo com a systemd.specialpágina de manual, você deve usar Before=poweroff.target.

desligar.target

A special target unit for shutting down and powering off the system.

Applications wanting to power off the system should start this unit.

runlevel0.target is an alias for this target unit, for compatibility with SysV.

Além disso, como mencionei em meu comentário, você deve colocar scripts personalizados em arquivos /etc/systemd/system/. O /usr/lib/systemd/system/diretório deve ser usado para scripts fornecidos pelo sistema.

Então, talvez algo assim:

[Unit]
Description=runs only upon shutdown
DefaultDependencies=no
Conflicts=reboot.target
Before=shutdown.target
Requires=poweroff.target

[Service]
Type=oneshot
ExecStart=/bin/true
ExecStop=/usr/local/bin/yourscript
RemainAfterExit=yes

Responder3

Ao ler as respostas aqui, parece haver muitos mal-entendidos sobre como o systemd funciona. Em primeiro lugar, não use conflitos para excluir um alvo. É necessário evitar que serviços conflitantes sejam executados ao mesmo tempo.

Se uma unidade tiver uma configuração Conflitos= em outra unidade, iniciar a primeira interromperá a segunda e vice-versa.

Unidade significa um arquivo .service para lançar um serviço específico, não um alvo a ser alcançado. Em outras palavras, Conflicts=reboot.targetna melhor das hipóteses, não tem sentido e, na pior, impedirá a reinicialização. Não faça isso. Isso não significa que não execute isso na reinicialização. Significa abortar este serviço ou o reboot.target dependendo do tempo e de como o systemd interpreta esse uso errôneo de conflitos.

Aqui está um exemplo de uma unidade atualmente configurada (também conhecida como arquivo .service) que é executada apenas no desligamento e não na reinicialização:

[Unit]
Description=Play sound
DefaultDependencies=no
Before=poweroff.target halt.target

[Service]
ExecStart=/usr/local/bin/playsound.sh
ExecStop=/usr/local/bin/playsound.sh
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=poweroff.target halt.target 

poweroff.target é equivalente ao antigo nível de execução do systemv, que só é alcançado no desligamento. halt.target é um caminho de desligamento alternativo usado pelo systemd e também não acessível pela reinicialização. A seção de instalação diz ao systemd para adicionar este serviço à lista que deve ser concluída antes poweroff.targetou halt.targetserá considerada alcançada.

Este serviço está instalado e em execução no meu sistema.

Responder4

Eu testei a maior parte da postagem aqui e em vários sites. O único que realmente funcionou para ser executado apenas na reinicialização (não na inicialização novamente - mas falhou quando shutdown-halt-poweroff) é o post de @benoit2600 . sua segunda postagem/solução

Mas depois de testar descobri que você pode usar na Unidade todos os 4 alvos e será executado quando um deles realmente for usado SOMENTE. Descanse de acordo com as necessidades dele e suas. Em "ExecStop = mycommand" acabei de digitar meu comando direto (pois não precisei de uma festança completa)

[Unit]
Conflicts=reboot.target poweroff.target halt.target shutdown.target

informação relacionada