В рамках процесса установки Ubuntu 16.04 (с нуля до полной настройки, с установкой большого количества дополнительного программного обеспечения и внесением изменений после установки) мне нужен способ запускать скрипты (которые загружаются во время установки) после следующей перезагрузки (и только при следующей перезагрузке), удалять скрипты и завершать установку еще одной перезагрузкой.
У меня уже есть служба, которую я использую для запуска скриптов после первой загрузки, но без их удаления (ее можно запустить снова позже, если потребуется), но теперь я обнаружил, что мне нужно запускать скрипты, которые впоследствии необходимо удалить, поскольку они содержат конфиденциальную информацию.
Служба systemd, которую я использую для других скриптов, выглядит так:
[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 и /root/bin/firstrun-wrapper добавляются во время установки. /etc/default/firstrun содержит пароль и удаляется скриптом firstrun-wrapper, что не позволяет службе снова запуститься после перезагрузки. firstrun-wrapper выполняет ряд скриптов, добавленных во время установки, и завершает работу перезагрузкой.
Эту службу можно будет использовать позже для запуска той же настройки (добавив файл /etc/default/firstrun).
Итак, мой вопрос.Как запустить скрипт после следующей перезагрузки, удалить скрипт после его выполнения, а после удаления скрипта запустить перезагрузку?
Для меня не имеет значения, используется ли systemd или нет, и меня вполне устраивает, что после этого в системе останется «пустой» (пустой означает не содержащий никакой важной/конфиденциальной информации) файл.
Моя первая мысль была изменить мою текущую службу. Я думал, что могу добавить еще один скрипт в firstrun-wrapper, который удаляет определенные файлы и изменяет firstrun-wrapper, чтобы больше их не включать, и выполнить этот скрипт через ExecStopPost, но это не запускается при завершении службы (насколько я могу судить). Даже если я могу изменить файл firstrun-wrapper во время его выполнения, я понимаю, что это будет плохой практикой, поэтому я стараюсь этого избегать.
решение1
Вам нужно запустить crontab -e
для пользователя, который будет запускать скрипт - sudo crontab -e
длякореньили sudo -u user_name -e
отредактировать crontab дляимя пользователя. Вставьте @reboot /path/to/file
(NB! Не забудьте пустую новую строку). Сам скрипт должен выглядеть так:
#!/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
Для автоматизации этого процесса можно использовать Ansible. Вот пример простого плейбука, я запустил его на своем локальном хосте:
---
- hosts: localhost
tasks:
- name: cron job
cron:
name: "a job for reboot"
special_time: reboot
job: "/path/to/file"
Сначала нужно запустить плейбук, он обновляет задания cron для root
. После перезагрузки скрипт должен быть удален так же, как и /var/spool/cron/crontabs/root
запись файла с@перезагрузитьstring. Вы можете изменить файл, чтобы полностью удалить crontab, если необходим root.