Exécuter un script uniquement au tout premier démarrage

12

Existe-t-il un moyen idiomatique dans Ubuntu d'exécuter un script uniquement la première fois qu'une machine est démarrée? (EC2).

Roberto Aloi
la source

Réponses:

14

Non. Mais vous voudrez peut-être placer votre script /etc/init.d/scriptet le supprimer automatiquement:

#!/bin/bash

echo "Bump! I'm your first-boot script."

# Delete me
rm $0
Andrejs Cainikovs
la source
Veuillez noter qu'il $0est spécifique à bash (version> = 3). À des fins de compatibilité, vous pouvez fournir un nom de fichier de script à la place, ce qui le rend moins générique:rm /etc/init.d/script
Andrejs Cainikovs
4
$ 0 n'est PAS spécifique à bash et il est pris en charge depuis bien plus longtemps que bash 3.x (et il est pris en charge dans Bourne, Korn, zsh et autres). Le point critique est de savoir si $ 0 contient une spécification de chemin d'accès complète ou relative. Voici un lien vers un moyen fiable d'obtenir le chemin complet si vous en avez besoin: stackoverflow.com/questions/4774054/…
Jim Dennis
7

Créez un fichier de suivi lors de l'exécution du script. Si le fichier existe déjà, quittez le script.

À M
la source
3
Bien que cela puisse ne pas sembler à première vue, cela peut être une meilleure solution que de supprimer le script car il conserve la possibilité de le déclencher à nouveau, si jamais vous le souhaitez.
msanford
7

Combiner les deux premières réponses En supposant que vous nommez votre script, /usr/local/bin/firstboot.shplacez-le à la fin de /etc/rc.local(ces scripts s'exécutent à chaque démarrage) les scripts vont comme ceci

#! / bin / bash

FLAG = "/ var / log / firstboot.log"
si [ ! -f $ FLAG]; ensuite
   # Mettez ici vos phrases d'initialisation
   echo "C'est le premier démarrage"

   #la ligne suivante crée un fichier vide pour ne pas exécuter le prochain démarrage
   touchez $ FLAG
autre
   écho "Ne rien faire"
Fi
Awi
la source
Cela ne fonctionne pas nécessairement avec sysmtemd. J'ai besoin d'ajouter un sleep 20 pour m'assurer qu'il s'agit du dernier script exécuté.
mrossi
Si vous le nommez /etc/rc.local/99-firstboot.sh, il devrait fonctionner en dernier.
JohnDavid
3

Je suis surpris des résultats que je constate pour la recherche d'un crochet de "premier démarrage" Ubuntu bien défini et pris en charge. On dirait que la foule Red Hat / Fedora / CentOS a ce problème depuis plus d'une décennie. L'équivalent Ubuntu le plus proche semble être oem-config-firstboot .

L'idée de simplement exécuter un rm $0testament fonctionnera. Mais techniquement, il y a des sémantiques intéressantes. Contrairement à la plupart des autres interpréteurs de scripts sous Unix, un script shell est lu et traité une ligne / instruction à la fois. Si vous dissociez ( rm) le fichier par-dessous, alors que l'instance du shell qui traite ce script fonctionne maintenant avec un fichier anonyme (tout fichier ouvert mais non lié).

Considérez un fichier comme celui-ci:

#!/bin/bash
rm $0
echo "I've removed myself: $0"
ls -l $0
cat <<COMMENTARY
   This is a test.
   I'm still here, because the "here" doc is being fed to 'cat'
   via the anonymous file through the open file descriptor.
   But I cannot be re-exec'd
COMMENTARY
exec $0

Si vous enregistrez cela dans quelque chose comme rmself.shet liez (dur) cela à quelque chose comme ça, l' tstexécution ./tstdevrait afficher quelque chose comme ceci en sortie:

$ ./tst 
I've removed myself: ./tst
ls: ./tst: No such file or directory
   This is a test.
   I'm still here, because the "here" doc is being fed to 'cat'
   via the anonymous file through the open file descriptor.
   But I cannot be re-exec'd
./tst: line 11: /home/jimd/bin/tst: No such file or directory
./tst: line 11: exec: /home/jimd/bin/tst: cannot execute: No such file or directory

Il y a maintenant quelques cas de coin étranges possibles en ce qui concerne les liens symboliques et les cas où le script a été invoqué en tant que nom nu (forçant le shell à rechercher $PATHle script.

Mais il semble que bash(au moins dans la version 3.2) précède $0le chemin s'il a recherché le chemin et laisse autrement $ 0 défini sur le chemin relatif ou absolu utilisé pour appeler le script. Il ne semble pas faire de chemins relatifs de normalisation ou de résolution ni de liens symboliques.

Le "premier démarrage" le plus propre pour Ubuntu serait probablement de créer un petit package (.deb) contenant un script à placer /etc/init.d/firstbootet un script de post-installation qui l'utilise update-rc.dpour le lier au niveau d'exécution 1 ( /etc/rc1.d) (en utilisant une commande comme:) update-rc.d firstboot defaults. .. puis demandez à la dernière ligne de désactiver ou de supprimer en utilisant quelque chose comme:update-rc.d firstboot disable

Voici un lien vers le HOWTO Debian update-rc.d

Jim Dennis
la source
0

Vous pouvez sauvegarder rc.local actuel sur rc.local.bak

Ensuite, vous pouvez avoir ce que vous voulez faire dans rc.local et à la fin juste mv /etc/rc.loca.bak /etc/rc.local.

lmojzis
la source
0

La question portait sur l'exécution d'un script au premier démarrage d'EC2. Vous pouvez utiliser cloud-inità cette fin.

Lors du lancement d'une nouvelle instance EC2, vous avez la possibilité de définir User datasous Advanced datails. Si vous y placez un cloud-initscript, il sera exécuté au premier démarrage uniquement.

Par exemple, vous pouvez placer les éléments suivants dans User data:

#cloud-config

runcmd:
  - /usr/bin/command1.sh
  - /usr/bin/command2.sh

La sortie sera écrite dans /var/log/cloud-init-output.log

Cloud-initpeut faire bien plus que cela. Il est spécialement conçu pour effectuer une initialisation précoce des instances cloud. Voir les documents ici: http://cloudinit.readthedocs.io/en/latest/index.html

Dima L.
la source