Executar um comando antes do desligamento

47

Eu quero executar um comando simples antes que o computador seja desligado (o tempo não é essencial).

Para a inicialização, posso usar /etc/rc.local; existe algo semelhante para o desligamento?

Note que eu ainda gostaria de usar o botão de desligamento integrado no menu; Ou seja, eu não quero usar um script personalizado toda vez que eu desligar por terminal - ele precisa ser automático.

    
por Primož Kralj 24.09.2012 / 10:37

4 respostas

40

O Linux Mint é baseado no Ubuntu, então estou achando que o sistema de runlevel é provavelmente o mesmo. No Ubuntu, os scripts para os diferentes runlevels são executados de acordo com sua presença nos diretórios /etc/rc[0-6].d . Runlevel 0 corresponde ao desligamento e 6 a reinicialização.

Normalmente, o script em si é armazenado em /etc/init.d e, em seguida, links simbólicos são colocados nos diretórios correspondentes aos níveis de execução de 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.

Os scripts em cada diretório de nível de execução serão executados em ordem asciibética , portanto, se o pedido dentro do runlevel for importante para você , escolha o nome do seu symlink em conformidade.

    
por 24.09.2012 / 11:02
7

Você precisa usar rc.shutdown o script de encerramento do Kernel do Linux. Citando a página de manual do OpenBSD :

When the system is shut down using the reboot(8) or halt(8) commands, or when init(8) is signalled to do so, or when a keyboard-requested halt is issued (if the architecture supports it), rc(8) is invoked with the argument ''shutdown''.

Então, você simplesmente abre o seu rc.shutdown e adiciona os comandos do shell que você quer executar.

ATUALIZAÇÃO: Como o Linux Mint é baseado no Ubuntu, que tem um procedimento diferente de inicialização / desligamento, aqui está o procedimento relevante para você:

Escreva o script de shell que você deseja executar e copie-o para o diretório relevante em /etc/rc*.d/ . O * corresponde ao nível de execução no qual você deseja que o script seja executado.
O Ubuntu segue a numeração do runlevel do Debian, então você tem o runlevel 0 para halt e runlevel 6 para reboot.

    
por 24.09.2012 / 11:02
5

Agora que as variantes do Ubuntu e o Mint mudaram para o systemd, descobri que minhas soluções antigas baseadas no acima são menos satisfatórias. Pesquisei na Web para descobrir como fazer isso com o systemd e acabei combinando a sabedoria dos outros e documentando-a como uma postagem no blog em blogspot. com.au contendo o seguinte tutorial.

Com o systemd você cria um ou dois arquivos para chamar seus scripts usando os modelos abaixo e executa alguns comandos. Simples.

Versão da GUI

Primeiro crie os scripts que você deseja executar na inicialização e / ou no desligamento. Eu criei .scopening_atstart e .scfullcopy_atend.

Em seguida, verifique se ambos são executáveis clicando com o botão direito do mouse no arquivo, selecionando propriedades e certificando-se de que, sob permissões, você tenha marcado a opção Permitir execução do arquivo como um programa.

Os dois arquivos que criei preenchem e salvam o conteúdo de um ramdisk. Eles também criam um arquivo no meu diretório pessoal para provar que o serviço está funcionando. Eles eram da forma:

#!/bin/sh
cp -pru /home/john/zRamdisk/subdirectory1/* /home/john/.wine/drive_c/subdirectory1/
rm /home/john/stop_time
date +%D' '%T > /home/john/stop_time

Então eu abri meu gerenciador de arquivos como root, abri /etc/systemd/system e criei um arquivo startup.service e um arquivo save-ramdisk.service. Obviamente, você pode escolher seus próprios nomes e nomes genéricos poderiam ter incluído um arquivo de inicialização chamado johns_start.service e um arquivo de desligamento chamado johns_shutdown.service. Apenas não escolha nomes de serviço existentes.

[Unit]
Description=Startup Applications

[Service]
Type=oneshot
RemainAfterExit=false
ExecStart=/home/john/.scopening_atstart

[Install]
WantedBy=multi-user.target

e

[Unit]
Description=Save Ramdisk to Wine drive C

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=/home/john/.scfullcopy_atend

[Install]
WantedBy=multi-user.target

Você pode usar os mesmos arquivos de serviço, substituindo o caminho completo do seu script executável pelo meu.

Finalmente para cada um execute o comando systemctl enable your_files_name (mas sem o serviço de sufixo). Então meu primeiro foi systemctl enable startup

Reinicie o computador uma vez para iniciar os serviços. O serviço de início será executado sempre que o systemd inserir o destino multiusuário e o serviço de parada quando sair do destino multiusuário. Arquivos de serviço alternativos com diferentes condições de ativação serão descritos abaixo.

Versão da CLI (linha de comando)

Esta descrição assume que você opera a partir do seu diretório home ao invés de / home / john, use sudo conforme necessário, e sua escolha de editor onde eu escrevo vim ou svim.

Crie scripts de shell de inicialização e desligamento com a primeira linha #!/bin/sh e torne-os executáveis usando chmod +x my_new_filename .

Crie dois arquivos como acima, ou neste exemplo, um arquivo para lidar com tarefas de inicialização e desligamento. Eu vou executar scripts no meu diretório home, mas @don_crissti mostra algumas alternativas em Stack Exchange .

vim /etc/systemd/system/start_and_stop.service

e copie no conteúdo do arquivo:

[Unit]
Description=Run Scripts at Start and Stop

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/home/john/.startup_commands  #your paths and filenames
ExecStop=/home/john/.shutdown_commands

[Install]
WantedBy=multi-user.target

Em seguida, ative o serviço com o comando:

systemctl enable start_and_stop

e reinicie seu sistema após o qual os serviços estarão ativos. Os comandos systemctl is-enabled start_and_stop e systemctl is-active start_and_stop podem ser usados no monitoramento de seus novos serviços.

Alterando as condições do acionador para desligamento

Os arquivos acima de tudo usam a abertura ou fechamento do ambiente multiusuário para iniciar a execução dos scripts. O arquivo abaixo usa o início de quatro processos potenciais de desligamento para iniciar seus scripts. Adicionar ou remover os alvos na linha Antes + a linha WantedBy permitirá que você faça distinções mais sutis:

Este arquivo foi proposto na segunda resposta deste post , mas não consegui executá-lo até adicionar uma seção de instalação.

Novamente, edite o script em /etc/systemd/service/ e ative-o usando systemctl enable your_file_name . Quando mudei os alvos, usei o comando systemclt disable file_name e, em seguida, reativei o link para os diretórios de destino. Reinicie e o serviço estará funcionando.

[Unit]
Description=Do something required
DefaultDependencies=no
Before=shutdown.target reboot.target halt.target
# This works because it is installed in the target and will be
#   executed before the target state is entered
# Also consider kexec.target

[Service]
Type=oneshot
ExecStart=/home/john/.my_script  #your path and filename

[Install]
WantedBy=halt.target reboot.target shutdown.target
    
por 08.07.2016 / 00:09
1

Para sistemas init baseados em dependência SysV usados no Debian Wheezy, Devuan e seus derivados e talvez outros, você pode imitar o comportamento de rc.shutdown análogo para rc.local da seguinte forma:

Adicione seus comandos ao seguinte esqueleto de /etc/rc.shutdown :

#!/bin/sh -e
#
# rc.shutdown
#

# <add your commands here, before exit 0>

exit 0

Salve o script e torne o arquivo executável com chmod a+x /etc/rc.shutdown .

Em seguida, adicione um novo script /etc/init.d/rc.shutdown ao seu sistema com o seguinte conteúdo:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          rc.shutdown
# Required-Start:
# Required-Stop:
# X-Stop-After:      umountroot
# Default-Start:
# Default-Stop:      0 6
# Short-Description: Run /etc/rc.shutdown if it exist
### END INIT INFO


PATH=/sbin:/usr/sbin:/bin:/usr/bin

. /lib/init/vars.sh
. /lib/lsb/init-functions

do_stop() {
    if [ -x /etc/rc.shutdown ]; then
            [ "$VERBOSE" != no ] && log_begin_msg "Running local shutdown scripts (/etc/rc.shutdown)"
        /etc/rc.shutdown
        ES=$?
        [ "$VERBOSE" != no ] && log_end_msg $ES
        return $ES
    fi
}

case "$1" in
    start)
        # No-op
        ;;
    restart|reload|force-reload)
        echo "Error: argument '$1' not supported" >&2
        exit 3
        ;;
    stop|status)
    do_stop
        exit 0
        ;;
    *)
        echo "Usage: $0 start|stop" >&2
        exit 3
        ;;
esac

Também torne esse script executável.

Crie os links simbólicos em /etc/rc[06].d:

cd /etc/rc0.d ; ln -s ../init.d/rc.shutdown K01rc.shutdown

e

cd /etc/rc6.d ; ln -s ../init.d/rc.shutdown K01rc.shutdown

Use insserv para corrigir os links simbólicos e criar os arquivos necessários .depend.boot, .depend.start e .depend.stop:

insserv -v

Você precisa ser root ou usar o sudo para todos os comandos mencionados acima.

    
por 25.04.2018 / 14:57