Führen Sie ein Skript nur beim ersten Start aus

12

Gibt es in Ubuntu eine idiomatische Möglichkeit, ein Skript nur beim ersten Booten einer Maschine auszuführen? (EC2).

Roberto Aloi
quelle

Antworten:

14

Nein. Vielleicht möchten Sie Ihr Skript aber auch /etc/init.d/scripteinfügen und selbst löschen:

#!/bin/bash

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

# Delete me
rm $0
Andrejs Cainikovs
quelle
Bitte beachten Sie, dass dies $0bash-spezifisch ist (Version> = 3). Aus Kompatibilitätsgründen können Sie stattdessen den Namen der rm /etc/init.d/script
Skriptdatei angeben
4
$ 0 ist NICHT bash-spezifisch und wird schon viel länger unterstützt als Bash 3.x (und wird in Bourne, Korn, zsh und anderen unterstützt). Der Knackpunkt ist, ob $ 0 eine vollständige oder relative Pfadangabe enthält. Hier ist ein Link zu einer zuverlässigen Methode, um den vollständigen Pfad bei Bedarf abzurufen
Jim Dennis
7

Erstellen Sie eine Tracking-Datei, wenn das Skript ausgeführt wird. Wenn die Datei bereits vorhanden ist, beenden Sie das Skript.

Tom
quelle
3
Dies scheint auf den ersten Blick nicht der Fall zu sein, ist jedoch möglicherweise eine bessere Lösung als das Löschen des Skripts, da es weiterhin die Möglichkeit bietet, es erneut auszulösen, falls Sie dies jemals möchten.
Msanford
7

Kombinieren der ersten beiden Antworten Angenommen, Sie nennen Ihr Skript /usr/local/bin/firstboot.sham Ende /etc/rc.local(dieses Skript wird bei jedem Start ausgeführt)

#! / bin / bash

FLAG = "/ var / log / firstboot.log"
wenn [ ! -f $ FLAG]; dann
   #Geben Sie hier Ihre Initialisierungssätze ein
   echo "Dies ist der erste Boot"

   #in der nächsten Zeile wird eine leere Datei erstellt, damit der nächste Start nicht ausgeführt wird
   Berühre $ FLAG
sonst
   Echo "Nichts tun"
fi
Awi
quelle
Dies funktioniert nicht unbedingt mit sysmtemd. Ich muss einen Schlaf 20 hinzufügen, um sicherzustellen, dass es das letzte Skript ist, das ausgeführt wird.
Mrossi
Wenn Sie es /etc/rc.local/99-firstboot.sh nennen, sollte es zuletzt ausgeführt werden.
JohnDavid
3

Ich bin überrascht über die Ergebnisse, die ich bei der Suche nach einem gut definierten und unterstützten Ubuntu "first boot" -Hook sehe. Scheint, als hätte die Red Hat / Fedora / CentOS-Menge dies seit über einem Jahrzehnt hinbekommen. Das nächste Ubuntu-Äquivalent scheint oem-config-firstboot zu sein .

Die Idee, einfach einen rm $0Willen auszuführen , funktioniert. Aber technisch gesehen gibt es einige interessante Semantiken. Im Gegensatz zu den meisten anderen Skript-Interpretern unter Unix wird ein Shell-Skript jeweils zeilenweise gelesen und verarbeitet. Wenn Sie die Verknüpfung ( rm) der Datei aufheben, funktioniert die Instanz der Shell, die dieses Skript verarbeitet, jetzt mit einer anonymen Datei (jede Datei, die geöffnet, aber nicht verknüpft ist).

Betrachten Sie eine Datei wie diese:

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

Wenn Sie das auf so etwas speichern rmself.shund (fest) mit so etwas verknüpfen, sollte beim tstAusführen ./tstFolgendes als Ausgabe angezeigt werden:

$ ./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

Nun gibt es einige merkwürdige mögliche Eckfälle in Bezug auf Symlinks und Fälle, in denen das Skript als leerer Name aufgerufen wurde (was die Shell zwingt, nach $PATHdem Skript zu suchen) .

Es scheint jedoch, dass bash(zumindest in Version 3.2) $0der Pfad vorangestellt wird, wenn der Pfad durchsucht wird, und ansonsten $ 0 auf den relativen oder absoluten Pfad gesetzt bleibt, der zum Aufrufen des Skripts verwendet wurde. Es scheint keine Normalisierungs- oder Auflösungspfade oder Symlinks zu geben.

Wahrscheinlich wäre das sauberste "firstboot" für Ubuntu, ein kleines Paket (.deb) zu erstellen, das ein Skript enthält, das abgelegt werden soll, /etc/init.d/firstbootund ein Post-Install-Skript, das verwendet wird update-rc.d, um es mit Runlevel 1 ( /etc/rc1.d) zu verknüpfen (mit einem Befehl wie :) update-rc.d firstboot defaults. .. und dann die letzte Zeile deaktivieren oder löschen lassen mit etwas wie:update-rc.d firstboot disable

Hier ist ein Link zum Debian update-rc.d-HOWTO

Jim Dennis
quelle
0

Sie können das aktuelle rc.local in rc.local.bak sichern

Dann kannst du die Sachen, die du machen willst, in rc.local haben und am Ende nur noch mv /etc/rc.loca.bak /etc/rc.local.

lmojzis
quelle
0

Die Frage betraf das Ausführen eines Skripts beim ersten Start von EC2. Sie können cloud-initfür diesen Zweck verwenden.

Beim Starten einer neuen EC2-Instanz haben Sie die Möglichkeit, User dataunter zu definieren Advanced datails. Wenn Sie dort ein cloud-initSkript platzieren, wird es nur beim ersten Start ausgeführt.

Beispielsweise können Sie Folgendes einfügen in User data:

#cloud-config

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

Die Ausgabe wird in geschrieben /var/log/cloud-init-output.log

Cloud-initkann noch viel mehr. Es wurde speziell für die frühe Initialisierung von Cloud-Instanzen entwickelt. Siehe die Dokumente hier: http://cloudinit.readthedocs.io/en/latest/index.html

Dima L.
quelle