Führen Sie das Skript beim nächsten Neustart aus und entfernen Sie es

Führen Sie das Skript beim nächsten Neustart aus und entfernen Sie es

Als Teil eines Ablaufs, der Ubuntu 16.04 installiert (von Grund auf bis zur vollständigen Konfiguration, mit viel installierter zusätzlicher Software und nach der Installation vorgenommenen Änderungen), brauche ich eine Möglichkeit, Skripte (die während der Installation heruntergeladen werden) nach dem nächsten Neustart (und nur dem nächsten Neustart) auszuführen, die Skripte zu entfernen und mit einem weiteren Neustart zu beenden.

Ich verfüge bereits über einen Dienst, den ich zum Ausführen von Skripten nach dem ersten Start verwende, ohne sie jedoch zu löschen (dies kann bei Bedarf zu einem späteren Zeitpunkt erneut ausgelöst werden). Jetzt stelle ich jedoch fest, dass ich Skripte ausführen muss, die anschließend gelöscht werden müssen, da sie vertrauliche Informationen enthalten.

Der systemd-Dienst, den ich für die anderen Skripte verwende, sieht folgendermaßen aus:

[Unit]
Description=First run specifics
After=network-online.target
Requires=network-online.target

[Service]
Type=simple
EnvironmentFile=/etc/default/firstrun
ExecStart=/root/bin/firstrun-wrapper "${PASSWORD}"

[Install]
WantedBy=multi-user.target

/etc/default/firstrun und /root/bin/firstrun-wrapper werden während der Installation hinzugefügt. /etc/default/firstrun enthält ein Passwort und wird vom Skript firstrun-wrapper gelöscht, wodurch verhindert wird, dass der Dienst nach einem Neustart erneut gestartet wird. firstrun-wrapper führt eine Reihe von Skripten aus, die alle während der Installation hinzugefügt wurden, und beendet die Installation mit einem Neustart.

Der Dienst kann später erneut verwendet werden, um dasselbe Setup auszuführen (durch Hinzufügen der Datei /etc/default/firstrun).

Meine Frage ist also:Wie kann ich nach dem nächsten Neustart ein Skript ausführen, das Skript nach der Ausführung entfernen und nach dem Entfernen des Skripts einen Neustart auslösen?

Dabei ist es mir egal, ob systemd verwendet wird oder nicht, und ich habe kein Problem damit, dass danach eine „leere“ (leer bedeutet, dass sie keine relevanten/sensiblen Informationen enthält) Datei auf dem System verbleibt.

Mein erster Gedanke war, meinen aktuellen Dienst zu ändern. Ich dachte, ich könnte ein weiteres Skript in firstrun-wrapper hinzufügen, das bestimmte Dateien entfernt und firstrun-wrapper so ändert, dass sie diese nicht mehr enthalten, und dieses Skript über ExecStopPost ausführen, aber das wird nicht durch die eigenständige Beendigung des Dienstes ausgelöst (soweit ich das beurteilen kann). Selbst wenn ich die firstrun-wrapper-Datei während der Ausführung ändern kann, ist mir klar, dass das eine schlechte Vorgehensweise wäre, also versuche ich, das zu vermeiden.

Antwort1

Sie müssen es crontab -efür den Benutzer ausführen, der das Skript ausführen wird - sudo crontab -efürWurzeloder sudo -u user_name -ezum Bearbeiten von crontab fürNutzername. Einfügen @reboot /path/to/file(NB! Leere neue Zeile nicht vergessen). Das Skript selbst sollte so aussehen:

#!/bin/bash
do_your_stuff
# remove from root specific crontab setting all the information about the script
sed -i '/@reboot \/path\/to\/file/d' /var/spool/cron/crontabs/root
# remove the script file itself
rm -- "$0"
# reboot the machine in 2 minutes
shutdown -r +2

Um diesen Prozess zu automatisieren, können Sie Ansible verwenden. Hier ist ein Beispiel für ein einfaches Playbook, das ich auf meinem lokalen Host ausgeführt habe:

---
- hosts: localhost
  tasks:
  - name: cron job
    cron:
      name: "a job for reboot"
      special_time: reboot
      job: "/path/to/file"

Zuerst müssen Sie das Playbook ausführen, es aktualisiert die Cron-Aufgaben für root. Nach dem Neustart sollte das Skript genauso gelöscht werden wie der /var/spool/cron/crontabs/rootDateieintrag mit@NeustartZeichenfolge. Sie können die Datei beliebig ändern, um Crontab für Root bei Bedarf vollständig zu löschen.

verwandte Informationen