Executar comando antes de desligar / reiniciar [duplicado]

18

Eu tenho uma máquina executando algumas VMs vagantes. O problema que tenho é que às vezes esqueço de desligar a VM antes de desligar ou reiniciar minha máquina. Por isso, minha máquina ficou presa com esta mensagem:waiting for vboxnet0 to become free

Pesquisei sobre soluções e encontrei esta página:

http://en.kioskea.net/faq/3348-ubuntu-executing-a-script-at-startup-and-shutdown

Eu tentei o que eles para o desligamento, mas não funciona.

Eu escrevi um arquivo sh para esse comando:

#!/bin/bash

cd ~/workspace/git/mediaservice
vagrant halt

alguma sugestão?

SERPRO
fonte
4
O método no link é válido e funciona em todas as versões do Linux, portanto, seu script está errado;) O usuário não é conhecido no desligamento, pois é feito pela raiz do usuário. Então solte o "~" e faça um caminho completo.
Rinzwind
Funciona? Eu segui um manuel semelhante, como gist.github.com/ymc-geha/8416723 mas não funcionou para mim no Ubuntu 14.04
user2135804
@ user2135804 Eu pensei que sim .. mas na verdade não funcionou para o Vagrant .. Tentei com outras coisas e funcionou bem.
SERPRO
1
A propósito, o bug que você está descrevendo está aqui .
Garrett
1
Como visto no relatório de erros, isso foi corrigido e será incluído no VirtualBox 4.3.29.
Garrett

Respostas:

11

Se suas VMs vagrantes estiverem usando o VirtualBox, você poderá modificar / etc / default / virtualbox e alterar a linha que diz:

SHUTDOWN_USERS=""

para

SHUTDOWN_USERS="all"

Isso foi corrigido para mim no Ubuntu 14.04

GaryBishop
fonte
1
Na verdade, existe um ticket aberto na caixa virtual conectada a isso. virtualbox.org/ticket/12264 . Eu sugiro usar em SHUTDOWN_USERS=`cut -d: -f1 /etc/passwd`vez deSHUTDOWN_USERS="all"
running.
Eu também estou no Ubuntu 14.04 com Vagrant usando VirtualBox, mas não tenho qualquer /etc/default/virtualboxarquivo ...
Garrett
21

Para executar um script no desligamento ou reinicialização:

  1. salve seu script em /etc/rc6.d
  2. Torne executável: sudo chmod +x K99_script

Notas:

  • O script em rc6.d deve estar sem extensão .sh
  • O nome do seu script deve começar com K99 para ser executado no momento certo.
  • Os scripts neste diretório são executados em ordem alfabética.

fonte

Maythux
fonte
1
De fato. Nomear corretamente para que seja executado no momento certo é muito importante.
Shivams
1
Coloquei um script em /etc/rc6.d e ele não foi executado no desligamento. Coloquei-o no /etc/rc0.d e ele foi executado no desligamento. Provavelmente, o rc.6 é apenas para reinicialização.
Erel Segal-Halevi
2
@Erel Segal-Halevi Acabei de tentar adicionar um script K99 ao /etc/rc6.d e ele não foi executado. Observando os outros scripts, existe um código de linha ** bold K10reboot -> ../init.d/reboot **, de modo que parece que um script K99 NUNCA será executado !!
David Walker
A resposta do Ravi abaixo é uma escolha melhor, pois usa links simbólicos para garantir que o script seja executado no desligamento e na reinicialização. Eu também acho que a maioria dos arquivos do sistema costuma adotar essa abordagem.
Eddie
12

Como fazer isso com o Systemd (é mais fácil)

Agora que as variantes do Ubuntu e o Mint foram para o systemd, achei minhas soluções antigas com base no exposto menos satisfatórias. Pesquisei na web para descobrir como fazer isso com o systemd e acabei combinando a sabedoria de outras pessoas e documentando-a como uma postagem de 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 desligamento. Basta fazer um se você não precisar de ambos. Criei .scopening_atstart e .scfullcopy_atend.

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

insira a descrição da imagem aqui

Os dois arquivos que eu 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 tinham a 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

Em seguida , abri meu gerenciador de arquivos como root, abri /etc/systemd/systeme criei um arquivo startup.service e um arquivo save-ramdisk.service. Obviamente, você pode escolher seus próprios nomes e nomes genéricos poderiam incluir 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 foisystemctl enable startup

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

Comandos úteis adicionais incluem:

systemctl é inicialização ativada
systemctl é inicialização ativada
systemctl reiniciar inicialização

Mais pode ser encontrado na referência acima.



Versão CLI (linha de comando)

Esta descrição supõe que você opere no diretório inicial em vez de em / home / john, use o sudo conforme necessário e sua escolha do editor em que escrevo vim ou svim.

Crie scripts de shell de inicialização e desligamento com a primeira linha #!/bin/she 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. Vou executar scripts no meu diretório pessoal, mas o @don_crissti mostra algumas alternativas no Stack Exchange .

svim /etc/systemd/system/start_and_stop.service

e copie o 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, ativar o serviço com o comando:

systemctl enable start_and_stop

e reinicie o sistema após o qual os serviços estarão ativos. Os comandos systemctl is-enabled start_and_stope systemctl is-active start_and_stoppodem 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 o fechamento do ambiente multiusuário para iniciar a execução dos scripts. O arquivo abaixo usa o início de quatro possíveis processos de desligamento para iniciar seus scripts. Adicionar ou remover os destinos na linha Antes + na linha WantedBy permitirá fazer distinções mais refinadas:

Este arquivo foi proposto na segunda resposta desta postagem, mas não consegui executá-lo até que eu adicionei uma seção Instalação.

Novamente, edite o script /etc/systemd/service/e ative-o usando systemctl enable your_file_name. Quando alterei os destinos, usei o systemclt disable file_namecomando e o reativei, que o vinculou aos diretórios de destino. Reinicialize e o serviço estará operando.

[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
John 9631
fonte
7
Mais fácil? mais fácil do que o que? mais fácil do que escalar o Everest? todas as outras soluções postadas aqui é mais fácil do que este ...
Fran Marzoa
Uau, essa é uma resposta completa e decentemente escrita, e o que todos deveriam fazer - os problemas de nomenclatura no /etc/rc6.d e a confusão indicam que essas não são boas respostas. Se um procedimento é simples, ele não necessariamente tem poder para atingir seu fim com segurança. Consulte a seção [Instalar] - você pode ter certeza de que seu script será executado na hora correta. Além disso, como uma resposta é longa, isso não significa que seja complexo! Graças btw, John9631, esta resposta é perfeito e será inestimável para a criação de scripts seguras e eficientes em um ponto crítico missão no tempo ...
moleiro o gorila
11
  1. Crie um arquivo executável do shell com seu script no diretório /etc/init.d/.

  2. Como isso precisa ser executado durante o desligamento ou a reinicialização, é necessário criar softlinks em /etc/rc0.d/ e /etc/rc6.d

Exemplo:

sudo ln -s /etc/init.d/<your_file> /etc/rc0.d/k99stop_vm
sudo ln -s /etc/init.d/<your_file> /etc/rc6.d/k99stop_vm
sudo chmod a+x /etc/init.d/<your_file>
Ravi
fonte
chmodaltera os sinalizadores de permissão do destino do link, que é o mesmo para os dois argumentos. A especificação de ambos é redundante.
David Foerster
2

Você pode encontrar uma solução aqui: Suspenda / retome todas as caixas do Vagrant no desligamento / inicialização do sistema .

Existe um script init simples que suspende todas as caixas em execução antes de desligar.

Instalação

Edite /etc/init.d/vagrant-boxese cole o script do artigo acima e salve. Ou faça o download aqui e salve-o em /etc/init.d/vagrant-boxes. No debian / ubuntu etc, execute

# update-rc.d vagrant-boxes defaults 99 01

O número 99 é o número da sequência e deve ser maior que (no meu caso, o Virtualbox número 20, que por sinal é o padrão nas distribuições Debian). O segundo número é a sequência ao desligar o computador. Portanto, pode ser bom fazer primeiro.

milkovsky
fonte
2

Para o Ubuntu 14.10 você algo como RC04nãoRC99

O que fazer do zero

  1. Crie um script em /etc/init.d/scriptName
  2. Link via ln -s /etc/rc6.d/K04scriptName /etc/init.d/scriptName

Passos pelos quais passei

  1. Tentei sem sucesso usar Ubuntu - Executando um script na inicialização e desligamento
  2. Encontrei o script de desligamento do Ubuntu 14.10 com rc0.d (rc6.d, rc.d)
  3. Mudei de /etc/rc6.d/RC99linkName para /etc/rc6.d/RC04linkName e funciona
Anthony Astige
fonte