Jalankan perintah sebelum mematikan

52

Saya ingin menjalankan perintah sederhana tepat sebelum komputer dimatikan (waktunya tidak penting).

Untuk startup, saya bisa menggunakan /etc/rc.local; adakah yang serupa dengan shutdown?

Perhatikan bahwa saya masih ingin menggunakan tombol shutdown terintegrasi dari menu; yaitu saya tidak ingin menggunakan skrip khusus setiap kali saya mematikan melalui terminal - itu harus otomatis.

Primož Kralj
sumber

Jawaban:

42

Linux Mint berbasis pada Ubuntu, jadi saya mencari sistem runlevel mungkin sama. Di Ubuntu, skrip untuk runlevel yang berbeda dijalankan sesuai dengan keberadaannya di /etc/rc[0-6].ddirektori. Runlevel 0 berhubungan dengan shutdown, dan 6 untuk reboot.

Biasanya skrip itu sendiri disimpan /etc/init.d, dan kemudian symlink ditempatkan di direktori yang sesuai dengan runlevel yang Anda butuhkan.

Jadi dalam kasus Anda, tulis skrip Anda, simpan di dalamnya /etc/init.d/, lalu buat symlink di masing-masing /etc/rc0.ddan /etc/rc6.d(jika Anda ingin keduanya) menunjuk ke skrip Anda.

Script di setiap direktori runlevel akan dieksekusi dalam urutan asciibetical , jadi jika urutan dalam runlevel penting bagi Anda, pilih nama symlink Anda sesuai.

ire_and_curses
sumber
Saya baru saja melihat file kerangka di init.d (tepat kubuntu) dan sedikit terintimidasi. Saya hanya ingin menambahkan beberapa perintah yang menggemakan tanggal penutupan menjadi file di bawah / var / log. Bisakah saya melakukan itu atau saya harus berurusan dengan beberapa hal lain dalam file kerangka?
Joe
2
@ Jo - Anda tidak perlu sebagian besar dari itu kecuali Anda ingin skrip Anda dapat dikontrol sebagai layanan standar. Anda tidak akan merusak apa pun dengan gema sederhana ke file log Anda sendiri, jadi cobalah dan lihat.
ire_and_curses
1
Berikut ini contoh skrip init.d sederhana. Selain itu, lebih mudah dan lebih kuat untuk menggunakan symlinksudo update-rc.d /etc/init.d/myservice defaults
RolfBly
Saya telah menulis /etc/init.d/spark_shutdown.sh dan membuat tautan di /etc/rc0.d & /etc/rc6.d sekarang bagaimana cara mengonfirmasi skrip ini berjalan di ubuntu aws ec2 instance
Ashish Karpe
10

Sekarang varian Ubuntu dan Mint telah pindah ke systemd saya menemukan solusi lama saya berdasarkan di atas menjadi kurang memuaskan. Saya mencari di seluruh web untuk mengetahui bagaimana melakukannya dengan systemd dan akhirnya menggabungkan kebijaksanaan orang lain dan mendokumentasikannya sebagai posting blog di blogspot.com.au yang berisi tutorial berikut.

Dengan systemd Anda membuat satu atau dua file untuk memanggil skrip Anda menggunakan templat di bawah ini, dan menjalankan beberapa perintah. Sederhana.


Versi GUI

Pertama buat skrip yang ingin Anda jalankan saat startup dan / atau shutdown. Saya membuat .scopening_atstart dan .scfullcopy_atend.

Kemudian pastikan keduanya dapat dieksekusi dengan mengklik kanan file, memilih properti dan memastikan bahwa, di bawah izin, Anda telah mencentang Izinkan mengeksekusi file sebagai program.

Dua file yang saya buat mengisi dan menyimpan konten ramdisk. Mereka juga membuat file di direktori rumah saya untuk membuktikan bahwa layanannya berfungsi. Mereka adalah bentuk:

#!/bin/sh
cp -pru /home/john/zRamdisk/subdirectory1/* /home/john/.wine/drive_c/subdirectory1/
rm /home/john/stop_time
date +%D' '%T > /home/john/stop_time

Kemudian saya membuka file manager saya sebagai root, membuka /etc/systemd/systemdan membuat file startup.service dan file save-ramdisk.service. Jelas Anda dapat memilih nama Anda sendiri dan nama generik dapat menyertakan file startup yang disebut johns_start.service dan file shutdown yang disebut johns_shutdown.service. Hanya saja, jangan memilih nama layanan yang ada.

[Unit]
Description=Startup Applications

[Service]
Type=oneshot
RemainAfterExit=false
ExecStart=/home/john/.scopening_atstart

[Install]
WantedBy=multi-user.target

dan

[Unit]
Description=Save Ramdisk to Wine drive C

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=/home/john/.scfullcopy_atend

[Install]
WantedBy=multi-user.target

Anda dapat menggunakan file layanan yang sama, menggantikan jalur lengkap skrip yang dapat dieksekusi untuk saya.

Akhirnya untuk masing-masing jalankan perintah systemctl aktifkan your_files_name (tetapi tanpa layanan akhiran). Jadi yang pertama adalahsystemctl enable startup

Nyalakan kembali komputer satu kali untuk memulai layanan. Layanan mulai akan dijalankan setiap kali systemd memasuki target multi-pengguna dan layanan berhenti ketika keluar dari target multi-pengguna. File layanan alternatif dengan berbagai kondisi aktivasi akan dijelaskan di bawah ini.


Versi CLI (Command Line)

Deskripsi ini mengasumsikan bahwa Anda beroperasi dari direktori home Anda daripada / home / john, gunakan sudo sesuai kebutuhan, dan editor pilihan Anda tempat saya menulis vim atau svim.

Buat skrip startup dan shutdown shell dengan baris pertama #!/bin/shdan buat agar dapat dieksekusi menggunakan chmod +x my_new_filename.

Buat dua file seperti di atas, atau dalam contoh ini, satu file untuk menangani tugas-tugas startup dan shutdown. Saya akan menjalankan skrip di direktori home saya tetapi @don_crissti menunjukkan beberapa alternatif di Stack Exchange .

vim /etc/systemd/system/start_and_stop.service

dan salin dalam konten file:

[Unit]
Description=Run Scripts at Start and Stop

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/home/john/.startup_commands  #your paths and filenames
ExecStop=/home/john/.shutdown_commands

[Install]
WantedBy=multi-user.target

Kemudian Aktifkan Layanan dengan perintah:

systemctl enable start_and_stop

dan reboot sistem Anda setelah itu layanan akan aktif. Perintah systemctl is-enabled start_and_stopdan systemctl is-active start_and_stopdapat digunakan dalam memonitor layanan baru Anda.


Mengubah Kondisi Pemicu Shutdown

File-file di atas semua menggunakan buka atau tutup lingkungan multi-pengguna untuk memulai menjalankan skrip. File di bawah ini menggunakan awal dari empat proses mematikan potensial untuk memulai skripnya. Menambahkan atau menghapus target pada baris Sebelum + baris WantedBy akan membuat Anda membuat perbedaan yang lebih baik:

File ini diusulkan pada jawaban kedua posting ini tetapi saya tidak dapat menjalankannya sampai saya menambahkan bagian Instal.

Sekali lagi, edit skrip /etc/systemd/service/dan aktifkan menggunakan systemctl enable your_file_name. Ketika saya mengubah target, saya menggunakan systemclt disable file_nameperintah dan kemudian mengaktifkannya kembali yang menghubungkannya dengan direktori target. Reboot dan layanan akan beroperasi.

[Unit]
Description=Do something required
DefaultDependencies=no
Before=shutdown.target reboot.target halt.target
# This works because it is installed in the target and will be
#   executed before the target state is entered
# Also consider kexec.target

[Service]
Type=oneshot
ExecStart=/home/john/.my_script  #your path and filename

[Install]
WantedBy=halt.target reboot.target shutdown.target
Yohanes 9631
sumber
7

Anda perlu menggunakan rc.shutdownskrip shutdown untuk Kernel Linux. Mengutip halaman manual OpenBSD :

Ketika sistem dimatikan menggunakan perintah reboot (8) atau halt (8), atau ketika init (8) ditandai untuk melakukannya, atau ketika penghentian yang diminta keyboard dikeluarkan (jika arsitektur mendukungnya), rc ( 8) dipanggil dengan argumen `` shutdown ''.

Jadi, Anda cukup membuka rc.shutdown dan menambahkan perintah shell apa pun yang ingin Anda jalankan.

UPDATE: Karena Linux Mint didasarkan pada Ubuntu, yang memiliki prosedur startup / shutdown yang berbeda, berikut adalah prosedur yang relevan untuk Anda:

Tulis skrip shell yang ingin Anda jalankan dan salin ke direktori yang relevan di blog Anda /etc/rc*.d/. The *bersesuaian dengan runlevel di mana Anda ingin script untuk mengeksekusi.
Ubuntu mengikuti penomoran runlevel Debian, sehingga Anda memiliki runlevel 0 untuk berhenti dan runlevel 6 untuk reboot.

darnir
sumber
1

Untuk sistem init berbasis ketergantungan SysV yang digunakan dalam Debian Wheezy, Devuan dan turunannya dan mungkin yang lain, Anda dapat meniru perilaku rc.shutdownanalog untuk rc.localmenyukai yang berikut ini:

Tambahkan perintah Anda ke kerangka berikut /etc/rc.shutdown:

#!/bin/sh -e
#
# rc.shutdown
#

# <add your commands here, before exit 0>

exit 0

Simpan skrip dan buat file tersebut dapat dieksekusi chmod a+x /etc/rc.shutdown.

Kemudian, tambahkan skrip baru /etc/init.d/rc.shutdownke sistem Anda dengan konten berikut:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          rc.shutdown
# Required-Start:
# Required-Stop:
# X-Stop-After:      umountroot
# Default-Start:
# Default-Stop:      0 6
# Short-Description: Run /etc/rc.shutdown if it exist
### END INIT INFO


PATH=/sbin:/usr/sbin:/bin:/usr/bin

. /lib/init/vars.sh
. /lib/lsb/init-functions

do_stop() {
    if [ -x /etc/rc.shutdown ]; then
            [ "$VERBOSE" != no ] && log_begin_msg "Running local shutdown scripts (/etc/rc.shutdown)"
        /etc/rc.shutdown
        ES=$?
        [ "$VERBOSE" != no ] && log_end_msg $ES
        return $ES
    fi
}

case "$1" in
    start)
        # No-op
        ;;
    restart|reload|force-reload)
        echo "Error: argument '$1' not supported" >&2
        exit 3
        ;;
    stop|status)
    do_stop
        exit 0
        ;;
    *)
        echo "Usage: $0 start|stop" >&2
        exit 3
        ;;
esac

Jadikan juga skrip ini dapat dieksekusi.

Buat symlink di /etc/rc[06[.d:

cd /etc/rc0.d ; ln -s ../init.d/rc.shutdown K01rc.shutdown

dan

cd /etc/rc6.d ; ln -s ../init.d/rc.shutdown K01rc.shutdown

Gunakan insservuntuk memperbaiki symlink dan membuat file .depend.boot, .depend.start, dan .depend.stop yang diperlukan:

insserv -v

Anda harus melakukan root atau menggunakan sudo untuk semua perintah yang disebutkan di atas.

Adrian Zaugg
sumber
Saya menyia-nyiakan waktu saya dengan yang ini sedikit hari ini dan tidak bisa bekerja dengan Ubuntu 16, mungkin itu saya tetapi solusi di atas langsung bekerja.
Mike Q