Запускать скрипт только при первой загрузке
Есть ли в Ubuntu идиоматический способ запуска скрипта только при первой загрузке машины? (EC2).
7 ответов
Нет. Но вы можете разместить свой сценарий в /etc/init.d/script
и удалите его самостоятельно:
#!/bin/bash
echo "Bump! I'm your first-boot script."
# Delete me
rm $0
Объединение первых двух ответов Предполагая, что вы называете свой сценарий /usr/local/bin/firstboot.sh
положить в конце /etc/rc.local
(этот скрипт запускается при каждой загрузке)
#!/ Bin / Баш FLAG="/ Var / Журнал /firstboot.log" если [! -f $FLAG ]; затем # Поместите здесь ваши предложения инициализации echo "Это первая загрузка" # следующая строка создает пустой файл, поэтому он не будет запускаться при следующей загрузке коснитесь $ FLAG еще эхо "Ничего не делать" фи
Создайте файл отслеживания при запуске скрипта. Если файл уже существует, выйдите из сценария.
В моем случае это была сборка кастомной системы и мне пришлось отказаться от использования cloud-init и размещения скрипта под
/etc/init.d/script
не сработало, поэтому я использовал systemd.
ФАЙЛ
/etc/systemd/system/firstboot.service
[Unit]
Description=One time boot script
[Service]
Type=simple
ExecStart=/firstboot.sh
[Install]
WantedBy=multi-user.target
а также
ФАЙЛ
/firstboot.sh
#!/bin/bash
SOME COMMANDS YOU WANT TO EXECUTE
systemctl disable firstboot.service
rm -rf /etc/systemd/system/firstboot.service
rm -f /firstboot.sh
Затем включите
(sudo) chmod +x /firstboot.sh
(sudo) systemctl enable firstboot.service
Этот работает отлично для меня.
Я удивлен результатами, которые я вижу при поиске четко определенного и поддерживаемого хука Ubuntu "первая загрузка". Похоже, толпа Red Hat / Fedora / CentOS уже более десяти лет добивается этого. Ближайший эквивалент Ubuntu - oem-config-firstboot.
Идея просто выполнить rm $0
буду работать. Но, технически, есть некоторая интересная семантика. В отличие от большинства других интерпретаторов сценариев в Unix, сценарий оболочки читается и обрабатывается по одной строке / инструкции за раз. Если вы отмените связь (rm
) файл из-под него, то, что экземпляр оболочки, которая обрабатывает этот скрипт, теперь работает с анонимным файлом (любой файл, который открыт, но не связан).
Рассмотрим такой файл:
#!/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
Если вы сохраните что-то вроде rmself.sh
и (трудно) связать это с чем-то вроде tst
затем работает ./tst
должен показать что-то вроде этого в качестве вывода:
$ ./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
Теперь есть несколько странных возможных угловых случаев в отношении символических ссылок и случаев, когда скрипт вызывался как голое имя (заставляя оболочку искать $PATH
для сценария.
Но похоже что bash
(по крайней мере, в версии 3.2) prepends $0
с путем, если он искал путь и в противном случае оставляет $0 установленным для любого относительного или абсолютного пути, использованного для вызова сценария. Кажется, он не выполняет ни нормализацию, ни разрешение относительных путей, ни символических ссылок.
Вероятно, наиболее чистой "первой загрузкой" для Ubuntu было бы создание небольшого пакета (.deb), содержащего скрипт для размещения в /etc/init.d/firstboot
и сценарий после установки, который использует update-rc.d
связать это с уровнем запуска 1 (/etc/rc1.d
) (используя команду вроде: update-rc.d firstboot defaults
)... а затем попросите последнюю строку выполнить деактивацию или удалить что-то вроде: update-rc.d firstboot disable
Вот ссылка на Debian update-rc.d HOWTO
Вопрос был о запуске скрипта при первой загрузке EC2. Ты можешь использовать cloud-init
для этого.
При запуске нового экземпляра EC2 у вас есть возможность определить User data
под Advanced datails
, Если вы разместите cloud-init
скрипт там будет выполняться только при первой загрузке.
Например, вы можете разместить следующее в User data
:
#cloud-config
runcmd:
- /usr/bin/command1.sh
- /usr/bin/command2.sh
Вывод будет записан в /var/log/cloud-init-output.log
Cloud-init
может сделать гораздо больше, чем это. Он разработан специально для ранней инициализации облачных экземпляров. Смотрите документы здесь: http://cloudinit.readthedocs.io/en/latest/index.html
Вы можете сделать резервную копию текущего rc.local в rc.local.bak
Затем вы можете получить то, что вы хотите сделать в rc.local, а в конце просто mv /etc/rc.loca.bak /etc/rc.local.