Exécuter la commande avant l'arrêt / le redémarrage [doublon]

19

J'ai une machine exécutant quelques VM vagabonds. Le problème que j'ai est que parfois j'oublie d'arrêter ces VM avant d'arrêter ou de redémarrer ma machine. À cause de cela, ma machine est bloquée avec ce message:waiting for vboxnet0 to become free

J'ai cherché des solutions et j'ai trouvé cette page:

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

J'ai essayé ce qu'ils arrêtaient, mais cela ne fonctionne pas.

J'ai écrit un fichier sh pour cette commande:

#!/bin/bash

cd ~/workspace/git/mediaservice
vagrant halt

Aucune suggestion?

SERPRO
la source
4
La méthode dans le lien est valide et fonctionne sur toutes les versions de linux donc votre script est faux;) L'utilisateur n'est pas connu à l'arrêt car il est fait par l'utilisateur root. Déposez donc le "~" et faites-en un chemin complet.
Rinzwind
Est-ce que ça marche? J'ai suivi un manuel similaire comme gist.github.com/ymc-geha/8416723 mais n'a pas fonctionné pour moi sur Ubuntu 14.04
user2135804
@ user2135804 Je pensais que c'était le cas .. mais en fait cela n'a pas fonctionné pour Vagrant .. J'ai essayé avec d'autres trucs et cela a bien fonctionné.
SERPRO
1
Soit dit en passant, le bogue que vous décrivez est ici .
Garrett
1
Comme vu dans le rapport de bogue, cela a été corrigé et sera inclus avec VirtualBox 4.3.29.
Garrett

Réponses:

12

Si vos machines virtuelles errantes utilisent VirtualBox, vous pouvez modifier / etc / default / virtualbox et changer la ligne qui lit:

SHUTDOWN_USERS=""

à

SHUTDOWN_USERS="all"

Cela m'a corrigé sur Ubuntu 14.04

GaryBishop
la source
1
En fait, il y a un ticket ouvert dans une boîte virtuelle connecté à cela. virtualbox.org/ticket/12264 . Je suggérerais d'utiliser SHUTDOWN_USERS=`cut -d: -f1 /etc/passwd`au lieu deSHUTDOWN_USERS="all"
running.t
Je suis également sur Ubuntu 14.04 avec Vagrant utilisant VirtualBox, mais je n'ai aucun /etc/default/virtualboxfichier ...
Garrett
21

Pour exécuter un script à l'arrêt ou au redémarrage:

  1. enregistrez votre script dans /etc/rc6.d
  2. Rendez-le exécutable: sudo chmod +x K99_script

Remarques:

  • Le script dans rc6.d doit être sans extension .sh
  • Le nom de votre script doit commencer par K99 pour s'exécuter au bon moment.
  • Les scripts de ce répertoire sont exécutés par ordre alphabétique.

la source

Maythux
la source
1
En effet. Le nommer correctement pour qu'il s'exécute au bon moment est très important.
shivams
2
J'ai mis un script dans /etc/rc6.d et il ne s'est pas exécuté à l'arrêt. Je l'ai mis dans /etc/rc0.d et il s'est exécuté à l'arrêt. Probablement, rc.6 est uniquement destiné au redémarrage.
Erel Segal-Halevi
2
@Erel Segal-Halevi J'ai juste essayé d'ajouter un script K99 à /etc/rc6.d et il ne s'est pas exécuté. En regardant les autres scripts, il y a une ligne ** bold K10reboot -> ../init.d/reboot ** code, donc il semble qu'un script K99 ne sera JAMAIS exécuté !!
David Walker
La réponse de Ravi ci-dessous est un meilleur choix car il utilise des liens symboliques pour garantir que le script s'exécute à la fois à l'arrêt ET au redémarrage. Je pense également que la plupart des fichiers système ont tendance à adopter cette approche.
Eddie
rc.6 semble être uniquement pour le redémarrage comme d'autres l'ont mentionné. Voir
Aelian
12

Comment le faire avec Systemd (c'est plus facile)

Maintenant que les variantes d'Ubuntu et Mint sont passées à systemd, j'ai trouvé que mes anciennes solutions basées sur ce qui précède étaient moins satisfaisantes. J'ai cherché sur le Web pour savoir comment le faire avec systemd et j'ai fini par combiner la sagesse des autres et la documenter sous la forme d'un article de blog sur blogspot.com.au contenant le tutoriel suivant.

Avec systemd, vous créez un ou deux fichiers pour appeler vos scripts à l'aide des modèles ci-dessous et exécutez quelques commandes. Facile.


Version GUI

Créez d' abord les scripts que vous souhaitez exécuter au démarrage et / ou à l'arrêt. Faites-en un si vous n'avez pas besoin des deux. J'ai créé .scopening_atstart et .scfullcopy_atend.

Ensuite , assurez - vous qu'ils sont à la fois exécutable en cliquant droit sur le fichier, la sélection des propriétés et faire en sorte que, dans les autorisations, vous avez coché Autoriser l' exécution du fichier comme un programme.

entrez la description de l'image ici

Les deux fichiers que j'ai créés remplissent et enregistrent le contenu d'un disque virtuel. Ils créent également un fichier dans mon répertoire personnel pour prouver que le service fonctionne. Ils étaient de la forme:

#!/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

J'ai ensuite ouvert mon gestionnaire de fichiers en tant que root, ouvert /etc/systemd/systemet créé un fichier startup.service et un fichier save-ramdisk.service. Évidemment, vous pouvez choisir vos propres noms et les noms génériques auraient pu inclure un fichier de démarrage appelé johns_start.service et un fichier d'arrêt appelé johns_shutdown.service. Ne choisissez pas les noms de service existants.

[Unit]
Description=Startup Applications

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

[Install]
WantedBy=multi-user.target

et

[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

Vous pouvez utiliser les mêmes fichiers de service, en substituant le chemin complet de votre script exécutable au mien.

Enfin pour chacun, exécutez la commande systemctl activez votre_nom_fichiers (mais sans le service de suffixe). Donc ma première étaitsystemctl enable startup

Redémarrez l'ordinateur une fois pour démarrer les services. Le service de démarrage sera exécuté chaque fois que systemd entre dans la cible multi-utilisateurs et le service d'arrêt lorsqu'il quitte la cible multi-utilisateurs. Des fichiers de service alternatifs avec différentes conditions d'activation seront décrits ci-dessous.

Les commandes utiles supplémentaires incluent:

systemctl est un démarrage activé
systemctl est un démarrage actif
systemctl redémarre le démarrage

Plus d'informations peuvent être trouvées à la référence ci-dessus.



Version CLI (ligne de commande)

Cette description suppose que vous opérez à partir de votre répertoire personnel plutôt que / home / john, utilisez sudo au besoin et votre choix d'éditeur où j'écris vim ou svim.

Créez des scripts shell de démarrage et d'arrêt avec la première ligne #!/bin/shet rendez-les exécutables à l'aide de chmod +x my_new_filename.

Créez deux fichiers comme ci-dessus, ou dans cet exemple, un fichier pour gérer les tâches de démarrage et d'arrêt. J'exécuterai des scripts dans mon répertoire personnel mais @don_crissti montre quelques alternatives sur Stack Exchange .

svim /etc/systemd/system/start_and_stop.service

et copiez dans le contenu du fichier:

[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

Activez ensuite le service avec la commande:

systemctl enable start_and_stop

et redémarrez votre système après quoi les services seront actifs. Les commandes systemctl is-enabled start_and_stopet systemctl is-active start_and_stoppeuvent être utilisées pour surveiller vos nouveaux services.



Modification des conditions de déclenchement pour l'arrêt

Les fichiers utilisent avant tout l'ouverture ou la fermeture de l'environnement multi-utilisateur pour lancer l'exécution des scripts. Le fichier ci-dessous utilise le début de quatre processus d'arrêt potentiels pour lancer ses scripts. L'ajout ou la suppression des cibles sur la ligne Avant + la ligne WantedBy vous permettra de faire des distinctions plus fines:

Ce fichier a été proposé dans la deuxième réponse de ce post, mais je n'ai pas pu le faire fonctionner avant d'avoir ajouté une section d'installation.

Encore une fois, modifiez le script /etc/systemd/service/et activez-le à l'aide de systemctl enable your_file_name. Lorsque j'ai changé les cibles, j'ai utilisé la systemclt disable file_namecommande, puis je l'ai réactivée, ce qui l'a liée aux répertoires cibles. Redémarrez et le service sera opérationnel.

[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
la source
7
Plus facile? plus facile que quoi? plus facile que de gravir l'Everest? toutes les autres solutions publiées ici sont plus faciles que celle-ci ...
Fran Marzoa
1
Wow, c'est une réponse complète et décemment écrite, et ce que tout le monde devrait faire - les problèmes de nommage avec /etc/rc6.d et la confusion indiquent que ce ne sont pas de bonnes réponses. Si une procédure est simple, elle n'a pas nécessairement le pouvoir d'atteindre sa fin en toute sécurité. Voir la section [Install] - vous pouvez être certain que votre script s'exécutera au bon moment. De plus, parce qu'une réponse est longue, cela ne veut pas dire que c'est complexe! Merci btw, John9631, cette réponse est parfaite et sera inestimable pour créer des scripts sûrs et efficaces à un moment critique de la mission ...
Miller the gorilla
11
  1. Créez un fichier exécutable shell avec votre script dans le répertoire /etc/init.d/.

  2. Étant donné que cela doit être exécuté pendant l'arrêt ou le redémarrage, vous devez créer des liens logiciels dans /etc/rc0.d/ et /etc/rc6.d

Exemple:

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
la source
chmodmodifie les drapeaux d'autorisation de la cible du lien, qui est le même pour les deux arguments. Les spécifier tous les deux est redondant.
David Foerster
2

Vous pouvez trouver une solution ici: Suspendre / reprendre toutes les cases Vagrant à l'arrêt / démarrage du système .

Il existe un simple script d'initialisation qui suspend toutes les boîtes en cours d'exécution avant de s'arrêter.

Installation

Modifiez /etc/init.d/vagrant-boxeset collez le script de l'article ci-dessus et enregistrez. Ou téléchargez-le ici et enregistrez-le dans /etc/init.d/vagrant-boxes. Sur debian / ubuntu, etc., exécutez

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

Le numéro 99 est le numéro de séquence et devrait être plus grand que (dans mon cas, la boîte virtuelle numéro 20, qui est d'ailleurs la valeur par défaut sur les distributions Debian). Le deuxième nombre est la séquence lors de l'arrêt de l'ordinateur. Donc, il pourrait être bon de le faire avant tout.

milkovsky
la source
2

Pour Ubuntu 14.10 vous quelque chose comme RC04pasRC99

Que faire à partir de zéro

  1. Créez un script sur /etc/init.d/scriptName
  2. Lien via ln -s /etc/rc6.d/K04scriptName /etc/init.d/scriptName

Étapes que j'ai traversées

  1. J'ai essayé en vain d'utiliser Ubuntu - Exécution d'un script au démarrage et à l'arrêt
  2. J'ai trouvé le script d'arrêt Ubuntu 14.10 avec rc0.d (rc6.d, rc.d)
  3. Je suis passé de /etc/rc6.d/RC99linkName à /etc/rc6.d/RC04linkName et cela fonctionne
Anthony Astige
la source