Запускайте сценарій лише при першому завантаженні


Відповіді:


14

Ні. Але, можливо, ви захочете розмістити свій скрипт /etc/init.d/scriptі самостійно видалити його:

#!/bin/bash

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

# Delete me
rm $0

Зверніть увагу, $0специфічний для bash (версія> = 3). Для сумісності ви можете надати ім'я файлу сценарію, зробивши це менш загальним:rm /etc/init.d/script
Андрейс Кайніков

4
$ 0 НЕ є специфічним для bash, і він підтримується набагато довше, ніж bash 3.x був навколо (і він підтримується в Bourne, Korn, zsh та інших). Точка стику - це, чи містить 0 доларів США повну або відносну специфікацію шляху. Ось посилання на надійний спосіб отримати повний шлях, якщо він вам потрібен: stackoverflow.com/questions/4774054/…
Джим Денніс

7

Створіть файл відстеження під час запуску сценарію. Якщо файл вже існує, закрийте сценарій.


4
Хоча на перший погляд це може здатися не таким, це може бути кращим рішенням, ніж видалення сценарію, оскільки він зберігає можливість запустити його знову, якщо вам це захочеться.
msanford

7

Поєднання перших двох відповідей Якщо припустити, що ви назвали свій сценарій, /usr/local/bin/firstboot.shпоставте його в кінці /etc/rc.local(цей сценарій працює на кожному завантаженні), сценарії виходять так

#! / бін / баш

FLAG = "/ var / log / firstboot.log"
якщо [! -f $ FLAG]; потім
   #Введіть сюди свої ініціалізаційні пропозиції
   echo "Це перший завантаження"

   # наступний рядок створює порожній файл, щоб він не запускав наступне завантаження
   торкніться $ FLAG
ще
   відлуння "Не робіть нічого"
фі

Це не обов'язково для роботи з системою. Мені потрібно додати режим сну 20, щоб переконатися, що це останній запуск сценарію.
mrossi

Якщо ви назвали його /etc/rc.local/99-firstboot.sh, він повинен працювати останнім.
JohnDavid

3

Я здивований результатам, який я бачу для пошуку чітко визначеного та підтримуваного гачка 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) він претендує $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-rc.d HOWTO


0

Ви можете створити резервну копію поточного rc.local на rc.local.bak

Тоді ви можете мати речі, які ви хочете зробити в rc.local, а в кінці просто mv /etc/rc.loca.bak /etc/rc.local.


0

Питання полягало у запуску сценарію при першому завантаженні системи 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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.