Intercepta a chamada de desligamento e executa o script para permitir ou impedir o desligamento

2

Neste momento, meu laptop está começando a ter problemas com hardware. Às vezes eu tenho que tentar 3 vezes antes de começar com sucesso. Eu estou tentando salvar o código que eu modifico no meu stick USB, mas às vezes eu esqueço. É por isso que estou me perguntando se existe uma maneira de executar um script quando o usuário deseja desligar o computador. Esse script verificará várias coisas e, dependendo da situação, cancelará o desligamento e solicitará que o usuário execute alguma ação (insira uma chave usb, por exemplo) ou execute algumas instruções (salve a usb se estiver lá) e permita desligamento depois. Devido a essa interação necessária com o usuário, apenas colocar o script em /etc/rc0.d não será suficiente.

Obrigado

    
por Karim Mtl 27.02.2018 / 01:08

2 respostas

2

Use inibidores do sistema

Publicação original está na seção abaixo e detalha como interceptar o comando /sbin/shutdown . Esta seção é baseada em inibidores do systemd .

De inibidor do systemd :

Nome

systemd-inhibit - Executa um programa com bloqueio de inibição

Sinopse

systemd-inhibit [OPTIONS...] [COMMAND] [ARGUMENTS...]

systemd-inhibit [OPTIONS...] --list

Descrição

systemd-inhibit pode ser usado para executar um programa com bloqueio de inibidor de desligamento, inatividade ou ocioso. O bloqueio será adquirido antes que a linha de comando especificada seja executada e liberada posteriormente.

Bloqueios de inibidor podem ser usados para bloquear ou atrasar solicitações de suspensão e desligamento do sistema do usuário, bem como o manuseio inativo automático do sistema operacional. Isso é útil para evitar a suspensão do sistema enquanto um disco óptico está sendo gravado ou operações semelhantes que não devem ser interrompidas.

Para obter mais informações, consulte a Documentação do desenvolvedor do bloqueio de inibidores .

Opções

As seguintes opções são compreendidas:

--what=

  • Obtém uma lista separada por dois-pontos de uma ou mais operações para inibir: "shutdown", "sleep", "ocioso", "handle-power-key", "manipular-suspender-chave", "manipular-hibernar- key "," handle-lid-switch ", para inibir reinicialização / desligamento / parada / kexec, suspensão / hibernação, detecção automática de inatividade ou manipulação de baixo nível da chave liga / desliga e da tampa, respectivamente . Se omitido, o padrão é "inativo: inatividade: desligamento".

--who=

  • Recebe uma string descritiva curta e legível para o programa que está bloqueando. Se não for passado, o padrão é a string da linha de comando.

--why=

  • Recebe uma string descritiva curta, legível por humanos, sobre o motivo do bloqueio. O padrão é "Razão desconhecida".

--mode=

  • Aceita "bloco" ou "atraso" e descreve como o bloqueio é aplicado. Se "bloco" é usado (o padrão), o bloqueio proíbe qualquer das operações solicitadas sem limite de tempo, e somente usuários privilegiados podem substituí-lo. Se "atraso" é usado, o bloqueio só pode atrasar as operações solicitadas por um tempo limitado. Se o tempo passar, o bloqueio é ignorado e a operação executada. O limite de tempo pode ser especificado em logind.conf (5) . Tenha em atenção que "atraso" só está disponível para "dormir" e "encerrar".

--list

  • Lista todos os bloqueios de inibição ativos em vez de adquirir um.

-h , --help

  • Imprima um breve texto de ajuda e saia.

--version

  • Imprima uma string de versão curta e saia.

Sair do status

Retorna o status de saída do programa executado.

Exemplo

# systemd-inhibit wodim foobar.iso

Isso queima a imagem ISO foobar.iso em um CD usando o wodim (1) Nota: o link é quebrado na documentação do systemd e inibe a suspensão, o desligamento do sistema e o tempo ocioso ao fazer isso.

Veja também

systemd (1) , logind.conf(5)

Original Post

No conceito, parece bem fácil. Basta encontrar o comando, renomeá-lo e substituí-lo por seu próprio script que chama a versão renomeada:

$ type -a shutdown
shutdown is /sbin/shutdown
$ sudo mv /sbin/shutdown /sbin/shutdownoriginal

Em seguida, edite seu próprio script em /sbin/shutdown contendo no mínimo:

#!/bin/bash
/sbin/shutdownoriginal

Em seguida, marque seu script como executável para todos:

$ sudo chmod a+x /sbin/shutdown

Voila! Tudo o que chama desligamento agora chama seu script, que então chama o comando original.

Na realidade, no momento em que seu script é chamado, as coisas podem não estar no estado esperado. Por exemplo, eu coloco alguns comandos para gravar o desligamento, mas eles não parecem funcionar:

echo "/sbin/shutdown custom script calling /sbin/shutdownoriginal"
shutdowntime='date'
echo "Last shutdown: $shutdowntime" >> /home/rick/shutdownlog.txt

O primeiro echo deveria ter aparecido em /var/log/syslog , mas não. O segundo echo deveria ter anexado uma linha ao arquivo de log, mas isso não aconteceu. Isso me diz que, no momento em que o comando /sbin/shutdown é executado, o log do sistema já está desativado e o sistema de E / S de arquivos está desligado.

Uma abordagem melhor seria olhar para o alvo de desligamento do systemd e / ou inibidores de entrada. Deixarei esta resposta aqui para outros que possam pensar que poderia / deveria / deveria funcionar.

Como sempre lembre-se YMMV - Y nosso M ileage M ay V ery.

    
por WinEunuuchs2Unix 27.02.2018 / 01:23
0

Eu analisei systemd-inhibit

O que entendi é que, quando você o usa antes de um comando, ele aguarda até que seu comando / script termine antes que o sistema seja desligado, há algumas opções para bloquear o desligamento, mas não parece óbvio fazer isso comigo. Por enquanto sua primeira sugestão funciona para mim (não me importo de digitar "shutdown" em vez da interface gráfica). Aqui está um script básico como exemplo:

#!/bin/bash

if [ ! -d /media/myusername/myusbname ]; then
  zenity --question --text "Are you sure you want to shutdown without saving? If not choose \"No\" and insert the usb key" 2> /dev/null
  answer=$?
else
  #save data
  answer=0
fi
if [ $answer -eq 0 ]; then
  /sbin/shutdownoriginal
else
  zenity --info --text="Shutdown canceled" 2> /dev/null
fi

Obrigado

    
por Karim Mtl 27.02.2018 / 20:45