Запускать скрипт только при первой загрузке

Есть ли в 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.

Другие вопросы по тегам