Scripts de logout: não concluídos no desligamento, reinicialização

5

Estou tentando fazer algumas coisas no logout e a tarefa pode levar até cinco minutos para ser concluída.

Se o usuário escolher Power off ou Reboot diretamente, o script será eliminado antes da conclusão. Se o usuário apenas escolher Log out , o script será executado sem problemas.

Eu tentei usar pam_exec e lightdm property session-cleanup-script para apontar para o meu script, mas é o mesmo em ambos os casos.

O script usado para fazer o teste é este:

#!/bin/bash
touch /tmpfile
for p in $(seq 0 300) ; do
    sleep 1
    echo $p >> /tmpfile
done

Ao sair, todos os 300 números são gravados no arquivo. Ao desligar ou reiniciar diretamente a partir da sessão do usuário, apenas 2 ou 3 números são gravados, então o script está sendo eliminado.

Como é tratado o desligamento por lightdm? Como posso garantir que meu script não está sendo morto?

Se você propor uma abordagem alternativa, tome cuidado para saber qual usuário está sendo desconectado e conseguir executar um script como esse usuário. Eu também preciso notificar o usuário sobre o que está acontecendo, então é melhor ficar no X se possível.

    
por Jorge Suárez de Lis 01.02.2013 / 11:03

3 respostas

0

Para lidar com isso, combinei três mecanismos:

  • Um script de logoff do Lightdm, que obtém as informações do usuário e as grava em um arquivo temporário, para que possamos saber quem está desligando o computador. Ele também faz a tarefa pesada no caso de não estarmos desligando ou reinicializando.
  • Scripts initrd tradicionais para executar tarefas pesadas ao desligar ou reinicializar.
  • Mensagens de status do Plymouth para fornecer feedback sobre essas tarefas pesadas ao desligar ou reinicializar.

Então, eu tenho o script de tarefas pesadas em /usr/local/bin/heavy.sh :

#!/bin/bash 
touch /tmpfile 
for p in $(seq 0 300) ; do
    sleep 1
    echo $p >> /tmpfile
    if [ ! -z $DISPLAY ] ; then
        notify-send "Written $p"
    else 
        plymouth message --text="Written $p" &>/dev/null
    fi
done

Essa tarefa pesada tenta gerar informações para o X. Se isso falhar, tente fazer isso em Plymouth.

Em seguida, adicionei esta linha à configuração do Lightdm em /etc/lightdm/lightdm.conf :

session-cleanup-script=/usr/local/sbin/logout-tasks.sh

O script referenciado escreve o usuário no logout e tenta executar a tarefa pesada:

#!/bin/bash
echo $USER > /run/last-logout-user
/usr/local/bin/heavy.sh

O script initrd, localizado em /etc/init.d/logout-heavy-task-at-shutdown :

#!/bin/bash
USER_RUN=$(cat /run/last-logout-user)
sudo -u $USER_RUN /usr/local/bin/heavy.sh

Isso inicia a tarefa como o último usuário desconectado ao encerrar e reiniciar, considerando que adicionamos os links correspondentes:

 update-rc.d -n logout-heavy-task-at-shutdown start 05 0
 update-rc.d -n logout-heavy-task-at-shutdown start 05 6

E é isso. A tarefa pesada pode precisar ser manipulada quando for eliminada por X e, em seguida, iniciada novamente pelo script initrd. Dependendo da tarefa, isso pode não ser um problema.

    
por Jorge Suárez de Lis 06.02.2014 / 15:36
2

No Ubuntu, scripts para diferentes runlevels são executados de acordo com sua presença nos diretórios /etc/rc[0-6].d . Runlevel 0 corresponde ao encerramento e 6 a reiniciar.

Normalmente, o script é armazenado em /etc/init.d e, em seguida, links simbólicos são colocados nos diretórios correspondentes aos runlevels que você precisa.

Portanto, no seu caso, escreva seu script, armazene-o em /etc/init.d/ e crie um link simbólico em cada um dos /etc/rc0.d e /etc/rc6.d (se quiser os dois) apontando para o seu script.

Crie um link simbólico como: /etc/rc0.d/K01myscipt -> /etc/init.d/myscript

Os scripts em cada diretório de nível de execução serão executados em ordem alfabética ASCII, portanto, se a ordem dentro do runlevel for importante para você, escolha o nome do seu link simbólico de acordo.

Espero que isso resolva isso. Não se esqueça de torne-o executável (sudo chmod + x myscript). Além disso, não tenho certeza, mas talvez você tenha que cancelar o desligamento no início do script - shutdown -c now e emiti-lo novamente no final - shutdown -h now .

Agora, para saber quem emitiu o comando shutdown :
1) Bem, você pode fazer isso com a ajuda do script wrapper da seguinte forma:

a. mv /sbin/shutdown /sbin/shutdown-orig e b. vim /sbin/shutdown #!/bin/sh echo "$USER has initiated the shutdown process" >> /var/log/shutdown.owner /sbin/shutdown-orig "$@" e c. chmod 755 /sbin/shutdown

2) Ou, um usuário normal só tem acesso ao comando shutdown por meio dos comandos sudo e sudo (geralmente) registrados em /var/log/ . Então, você pode verificar isso. Espero que ajude. Para mais informações, consulte o meu tópico aqui . Não se esqueça de parar e dizer obrigado a eles.

EDIT: Concluindo, Se nada funcionar, tente usar sudo e parede de acesso ao desligamento / reinicialização e, em seguida, só você pode verificar se há logs e saber quem iniciou o processo de desligamento. Detalhes no conteúdo abaixo. Obrigado. Wonderful Question, Learnt a Lot.

    
por ASCIIbetical 28.12.2013 / 10:58
1

LightDM

Crie um script em /etc/rc0.d .

sudo vim /etc/rc0.d/myScript
sudo chmod +x /etc/rc0.d/myScript

GDM

Adicione seu comando ao arquivo /etc/gdm/PostSession/Default antes da linha exit 0 .

Como antes do desligamento, o usuário está desconectado de qualquer maneira, isso deve cobrir ambas as bases.

    
por abhshkdz 01.02.2013 / 11:36