Jalankan skrip hanya pada saat boot pertama

12

Apakah ada cara idiomatis di Ubuntu untuk menjalankan skrip hanya saat mesin pertama kali di-boot? (EC2).

Roberto Aloi
sumber

Jawaban:

14

Tidak. Tapi Anda mungkin ingin menempatkan skrip Anda /etc/init.d/script, dan menghapusnya sendiri:

#!/bin/bash

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

# Delete me
rm $0
Andrejs Cainikovs
sumber
Harap dicatat, $0khusus untuk bash (versi> = 3). Untuk tujuan kompatibilitas, Anda dapat memberikan nama file skrip, menjadikannya kurang umum:rm /etc/init.d/script
Andrejs Cainikovs
4
$ 0 BUKAN spesifik bash dan telah didukung lebih lama daripada bash 3.x telah ada (dan didukung di Bourne, Korn, zsh, dan lainnya). Poin yang menonjol adalah apakah $ 0 berisi spesifikasi path lengkap atau relatif. Berikut ini tautan ke cara yang andal untuk mendapatkan jalur lengkap jika Anda memerlukannya: stackoverflow.com/questions/4774054/…
Jim Dennis
7

Buat file pelacakan saat skrip berjalan. Jika file sudah ada, keluar dari skrip.

Tom
sumber
3
Meskipun mungkin tidak tampak seperti itu pada pandangan pertama, ini mungkin solusi yang lebih baik daripada menghapus skrip karena tetap memiliki kemungkinan untuk memicunya lagi, jika Anda mau.
msanford
7

Menggabungkan dua jawaban pertama Asumsikan Anda menamai skrip Anda, /usr/local/bin/firstboot.shtaruh di akhir /etc/rc.local(skrip ini berjalan pada setiap boot) skrip berjalan seperti ini

#! / bin / bash

FLAG = "/ var / log / firstboot.log"
jika [! -f $ FLAG]; kemudian
   # Masukkan kalimat inisialisasi Anda di sini
   echo "Ini boot pertama"

   # baris berikutnya membuat file kosong sehingga tidak akan menjalankan boot berikutnya
   sentuh $ FLAG
lain
   gema "Jangan lakukan apa-apa"
fi
Awi
sumber
Ini belum tentu bekerja dengan sysmtemd. Saya perlu menambahkan 20 tidur untuk memastikan itu adalah skrip terakhir.
mrossi
Jika Anda beri nama /etc/rc.local/99-firstboot.sh, ia harus dijalankan terakhir.
JohnDavid
3

Saya terkejut dengan hasil yang saya lihat untuk mencari kait "boot pertama" Ubuntu yang terdefinisi dengan baik dan didukung. Sepertinya kerumunan Red Hat / Fedora / CentOS telah dipaku selama lebih dari satu dekade. Setara dengan Ubuntu terdekat tampaknya adalah oem-config-firstboot .

Gagasan hanya melakukan rm $0kehendak bekerja. Tapi, secara teknis ada beberapa semantik menarik yang terlibat. Tidak seperti kebanyakan penerjemah skrip lainnya di bawah Unix, skrip shell dibaca dan diproses satu baris / pernyataan setiap kali. Jika Anda memutuskan tautan ( rm) file keluar dari bawahnya maka instance dari shell yang memproses skrip itu sekarang bekerja dengan file anonim (file apa pun yang terbuka tetapi tidak terhubung).

Pertimbangkan file seperti ini:

#!/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

Jika Anda menyimpannya ke sesuatu seperti rmself.shdan (menghubungkan) ke sesuatu seperti itu tstmaka menjalankannya ./tstakan menampilkan sesuatu seperti ini sebagai keluaran:

$ ./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

Sekarang ada beberapa kemungkinan kasus sudut aneh berkaitan dengan symlinks dan kasus-kasus di mana skrip dipanggil sebagai nama kosong (memaksa shell untuk mencari $PATHskrip.

Tetapi tampaknya bash(setidaknya dalam versi 3.2) menambahkan $0dengan path jika ia mencari path dan jika tidak meninggalkan $ 0 set ke apa pun relatif atau absolut path digunakan untuk menjalankan skrip. Tampaknya tidak melakukan normalisasi atau resolusi jalur relatif atau symlink.

Mungkin "firstboot" terbersih untuk Ubuntu adalah membuat paket kecil (.deb) yang berisi skrip untuk ditempatkan /etc/init.d/firstbootdan skrip post-install yang digunakan update-rc.duntuk menautkan itu ke runlevel 1 ( /etc/rc1.d) (menggunakan perintah seperti:) update-rc.d firstboot defaults. .. dan kemudian mintalah baris terakhir melakukan penonaktifan atau menghapus menggunakan sesuatu seperti:update-rc.d firstboot disable

Berikut tautan ke pembaruan Debian-rc.d HOWTO

Jim Dennis
sumber
0

Anda dapat mencadangkan rc.local saat ini ke rc.local.bak

Maka Anda dapat memiliki hal-hal yang ingin Anda lakukan di rc.local dan pada akhirnya hanya mv /etc/rc.loca.bak /etc/rc.local.

lmojzis
sumber
0

Pertanyaannya adalah tentang menjalankan skrip saat boot pertama EC2. Anda dapat menggunakan cloud-inituntuk tujuan ini.

Saat meluncurkan instance EC2 baru Anda memiliki opsi untuk mendefinisikan di User databawah Advanced datails. Jika Anda menempatkan cloud-initskrip di sana, skrip akan dijalankan hanya saat boot pertama.

Misalnya, Anda dapat menempatkan yang berikut ini di User data:

#cloud-config

runcmd:
  - /usr/bin/command1.sh
  - /usr/bin/command2.sh

Output akan ditulis ke /var/log/cloud-init-output.log

Cloud-initdapat melakukan lebih dari ini. Ini dirancang khusus untuk melakukan inisialisasi awal dari instance cloud. Lihat dokumen di sini: http://cloudinit.readthedocs.io/en/latest/index.html

Dima L.
sumber