Apa pengganti yang tepat untuk rc.local di systemd alih-alih membuat kembali rc.local

25

Saya tidak dapat menemukan cara yang benar untuk menjalankan beberapa skrip lokal (atau perintah yang sangat lokal) di systemd, saya sudah tahu saya tidak boleh membuat layanan (dalam systemd unit) untuk jenis skrip ini (atau saya harus?) ....

Solusi yang saya temukan adalah membuat rc.local dan memberikan izin eksekusi padanya.

printf '#!/bin/bash \n\nexit 0' >/etc/rc.local 
chmod +x /etc/rc.local

Misalnya, jika saya mendapatkan server lama dengan rc.local sederhana yang dikonfigurasikan oleh Anda, saya akan tahu apa yang Anda lakukan dan seberapa parahnya untuk memutakhirkan atau menginstal sesuatu yang baru di distro, karena rc.local dihormati oleh eksternal paket, tetapi di sisi lain jika saya menginstal server dan membuat unit systemd atau dua atau tiga (atau bahkan layanan sysvinit), hanya untuk melakukan tugas sederhana, ini kadang-kadang dapat membuat hidup Anda lebih sulit, dan lebih dari ini unit saya nama suatu hari nanti dapat bertentangan dengan nama-nama layanan baru yang dibuat oleh pengembangan distribusi, dan mungkin diinstal pada peningkatan, menyebabkan masalah untuk skrip saya!

Saya melihat pertanyaan lain bertanya tentang di mana rc.local dan jawabannya adalah untuk menciptakan dan memberikan hak akses eksekusi, saya pikir pertanyaan saya adalah benar-benar tidak sebuah duplikat , karena saya tidak ingin tahu di mana itu - percayalah, aku hanya ingin untuk menerima bahwa itu sudah usang , tetapi saya tidak dapat menemukan cara yang benar untuk melakukan hal-hal semacam ini, haruskah saya benar-benar membuat unit hanya untuk beberapa hal sederhana seperti itu?

Luciano Andress Martini
sumber
4
systemd "satu-satunya langkah yang menang bukanlah bermain"; sebagai alternatif, tergantung pada apa yang Anda inginkan, Anda dapat membuat Unit Systemd. Saya mungkin akan menggunakan rc.local untuk saat ini, dan peduli ketika itu hilang.
Rui F Ribeiro
Jadi menurut Anda cara resmi adalah membuat unit seperti layanan? Silakan posting sebagai jawaban bagaimana melakukan itu.
Luciano Andress Martini
1
Ketika saya mencoba Ubuntu saya membuat Unit untuk memiliki caching ssh-agent persisten di desktop saya sementara saya tidak reboot dan yang lain untuk sesuatu yang lain saya tidak ingat; Anda juga dapat membuat satu menunjuk ke /etc/rc.local tetapi tampaknya sistem melakukannya untuk Anda sendiri untuk saat ini .... Saya akan rc.local untuk saat ini, dan jika dihentikan, buat satu menunjuk ke palsu /etc/rc.local lalu.
Rui F Ribeiro
Ini kemungkinan akan merusak dokumentasi seolah-olah beberapa buku mengatakan bahwa Anda harus meletakkan sesuatu di /etc/rc.local, dan Anda mencoba untuk memutakhirkan dokumen ini, dengan mengatakan misalnya bahwa rc.local harus ditandai sebagai dapat dieksekusi, ketika buku itu benar-benar usang dokumentasi rusak, tetapi jika Anda mengatakan bahwa Anda harus membuat unit untuk menunjuk ke /etc/rc.local, dokumentasi brokes ini karena systemd bertentangan dengan unit Anda. Saya percaya jika Anda benar, mereka mungkin tidak memutuskan apakah itu sudah usang atau tidak, karena mereka masih belum memiliki pengganti ... ketika mereka memutuskan semua dokumentasi akan rusak lagi.
Luciano Andress Martini
Jenis skrip apa yang perlu Anda jalankan? Systemd memiliki banyak tipe unit. "Layanan" hanya satu dari banyak jenis unit . Misalnya Mount unit, unit automount, unit timer, unit target. Bisakah salah satu dari mereka memecahkan masalah Anda?
andcoz

Jawaban:

17

Seperti yang ditunjukkan di tempat lain, itu menjadi tidak bersih untuk digunakan di rc-local.servicebawah systemd.

  1. Secara teori dimungkinkan distribusi Anda tidak akan mengaktifkannya. (Saya pikir ini tidak umum, misalnya karena menonaktifkan opsi build yang sama juga menghapus poweroff/ rebootperintah yang banyak digunakan orang).
  2. Semantiknya tidak sepenuhnya jelas. Systemd mendefinisikan rc-local.servicesatu cara, tetapi Debian menyediakan file drop-in yang mengubah setidaknya satu pengaturan penting.

rc-local.servicesering bisa bekerja dengan baik. Jika Anda khawatir tentang hal di atas, yang perlu Anda lakukan adalah membuat salinannya sendiri! Inilah keajaibannya:

# /etc/systemd/system/my-startup.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/libexec/my-startup-script

[Install]
WantedBy=multi-user.target

Saya rasa Anda tidak perlu memahami setiap detail [*], tetapi ada dua hal yang perlu Anda ketahui di sini.

  1. Anda harus mengaktifkan ini dengan systemctl enable my-startup.service.

  2. Jika skrip Anda memiliki ketergantungan pada layanan lain, termasuk network-online.target, Anda harus mendeklarasikannya. Misal menambahkan [Unit]bagian, dengan garis Wants=network-online.targetdan After=network-online.target.

    Anda tidak perlu khawatir tentang ketergantungan pada layanan "boot awal" - khususnya, layanan yang sudah dipesan sebelumnya basic.target. Layanan seperti my-startup.servicesecara otomatis dipesan setelahnya basic.target, kecuali jika ditetapkan DefaultDependencies=no.

    Jika Anda tidak yakin apakah salah satu dependensi Anda adalah layanan "boot awal", satu pendekatan adalah mendaftar layanan yang dipesan sebelumnya basic.target, dengan menjalankan systemctl list-dependencies --after basic.target. (Catat itu --after, bukan --before).

Ada beberapa pertimbangan yang menurut saya juga berlaku untuk pre-systemd rc.local:

  1. Anda perlu memastikan perintah Anda tidak bertentangan dengan program lain yang mencoba mengendalikan hal yang sama.
  2. Cara terbaik adalah tidak memulai program yang sudah berjalan lama alias daemon dari rc.local.

[*] Saya menggunakan Type=oneshot+ RemainAfterExit=yeskarena lebih masuk akal untuk sebagian besar skrip sekali pakai . Ini memformalkan bahwa Anda akan menjalankan serangkaian perintah, yang my-startupakan ditampilkan sebagai "aktif" setelah mereka selesai, dan bahwa Anda tidak akan memulai daemon.

sourcejedi
sumber
Ya, ada semacam tempat "lokal" untuk membuat layanan atau cuplikan, atau apa pun - atau bisakah saya percaya ini lokal dan tidak boleh diubah? jika saya mengembangkan daemon saya sendiri? Karena saya tidak ingin mengubah keaslian sistem, jadi ketika saya menginstal beberapa apt-get saya tidak ingin melihat sistem saya terbakar karena skrip diganti, atau sesuatu seperti ini misalnya. Saya hanya ingin percaya bahwa dasmon hanya akan dimulai sekali saja, tanpa melakukan hal-hal gila tambahan yang saya takuti ... seperti mencoba untuk me-restart sebagai tak terbatas jika rusak, dll ...
Luciano Andress Martini
1
@LucianoAndressMartini jika Anda bertanya apa cara yang tepat untuk memulai daemon, Anda harus benar-benar menentukan layanan individual untuknya. Itu bisa menjadi .serviceunit sistem asli , atau jika Anda benar-benar ingin menulis skrip init LSB Anda dapat melakukannya. Saya tidak ingin merekomendasikan menempatkan beberapa daemon rc-local.serviceatau yang setara, saya pikir itu mungkin berhasil, tetapi tampaknya jauh lebih baik jika Anda dapat me-restart masing-masing daemon dengan systemctl restart my-daemonseperti yang lainnya. Ini dimaksudkan agar Anda memasukkan layanan lokal Anda /etc/systemd/system.
sourcejedi
1
@LucianoAndressMartini Anda harus menghindari menggunakan nama yang sama dengan layanan lain - seperti di sysvinit. Dalam situasi yang sama saya kadang-kadang mulai nama saya dengan local-...
sourcejedi
1
Terima kasih!!! Disimpan setelah setengah hari. Detail ini sangat penting bagi saya: Jenis = oneshot, RemainAfterExit = ya, Ingin = network-online.target, After = network-online.target. Hanya menggunakan build apache dan mengatur IP statis ke 192.168.1.80, sehingga router dapat mengarahkan lalu lintas di sana. Harus sepele. Sangat mengganggu di Debian9. Hampir tidak ada saran online kecuali "apt-get apache", "systemctl start apache" atau instruksi dengan init.d, tidak ada satupun yang berlaku untuk Apache yang dibuat sumber di bawah Debian9.
MichaelsonBritt
1
@MichaelsonBritt Yang terbaik adalah tidak memulai program yang sudah berjalan lama alias daemon dari rc.local. Saya menggunakan Type=oneshot... itu memformalkan bahwa ... Anda tidak akan memulai daemon. Jika Anda ingin informasi tentang memulai daemon, silakan ajukan pertanyaan baru.
sourcejedi
15

Lupakan rc.local.

Seperti yang saya katakan tentang CentOS 7 dan tentang Debian 8 dan tentang Ubuntu 15 :

Anda menggunakan sistem operasi systemd + Linux. /etc/rc.localadalah mekanisme kompatibilitas mundur ganda dalam systemd, karena ini merupakan mekanisme kompatibilitas mundur untuk mekanisme yang dengan sendirinya merupakan mekanisme kompatibilitas dalam klon van Smoorenburg System 5 rc.

Menggunakan /etc/rc.localbisa salah besar. Orang-orang terkejut dengan fakta bahwa systemd tidak berjalan rc.localdengan cara yang sama, di tempat yang sama di bootstrap, seperti yang biasa mereka lakukan. (Atau keliru berharap: Sebenarnya, itu tidak berjalan terakhir dalam sistem lama, seperti yang ditunjukkan oleh manual OpenBSD.) Yang lain terkejut dengan fakta bahwa apa yang mereka atur dalam rc.localmengharapkan cara lama dalam melakukan sesuatu, adalah kemudian benar-benar dibatalkan oleh orang-orang seperti baru udevaturan, NetworkManager, systemd-logind, systemd-resolved, atau berbagai "Kit" s.

Seperti dicontohkan oleh " Mengapa` init 0` menghasilkan "Kelebihan Argumen" pada Arch instal? ", Beberapa sistem operasi sudah menyediakan systemd tanpa fitur kompatibilitas mundur seperti systemd-rc-local-generatorgenerator . Sementara Debian masih mempertahankan fitur kompatibilitas ke belakang , Arch Linux membangun systemd dengan mereka dimatikan . Jadi pada Arch dan sistem operasi seperti itu diharapkan /etc/rc.local sepenuhnya diabaikan .

Lupakan rc.local. Itu bukan cara untuk pergi. Anda memiliki systemd + sistem operasi Linux. Jadi buatlah unit layanan systemd yang tepat, dan jangan mulai dari titik yang dua tingkat kompatibilitas mundur. (Di Ubuntu dan Fedora, tiga kali dihapus, klon van Smoorenburg System 5 rcyang diikuti rc.localkemudian telah dua kali digantikan, lebih dari satu dekade yang lalu, pertama oleh pemula dan kemudian oleh systemd.)

Juga ingat aturan pertama untuk bermigrasi ke systemd .

Ini bahkan bukan ide baru yang khusus untuk systemd. Pada sistem van Smoorenburg rcdan Upstart, yang harus dilakukan adalah membuat rcskrip van Smoorenburg yang tepat atau file pekerjaan pemula daripada menggunakan rc.local. Bahkan catatan manual FreeBSD bahwa saat ini orang membuat rcskrip Mewburn yang tepat alih-alih menggunakan /etc/rc.local. Mewburn rcdiperkenalkan oleh NetBSD 1.5 pada tahun 2000.

/etc/rc.localtanggal dari waktu Edisi Ketujuh Unix dan sebelumnya. Itu digantikan oleh /etc/inittabdan berbasis runlevel rcdi AT&T Unix System 3 (dengan sedikit berbeda /etc/inittabdi AT&T Unix System 5) pada tahun 1983 . Bahkan itu sekarang sejarah.

Buat definisi layanan asli yang tepat untuk sistem manajemen layanan Anda, apakah itu bundel layanan untuk nosh toolset service-managerdan system-control, /etc/rc.d/skrip untuk Mewburn rc, file unit layanan untuk systemd, file pekerjaan untuk Pemula, direktori layanan untuk runit / s6 / daemontools -encore, atau bahkan /etc/init.d/naskah untuk van Smoorenburg rc.

Dalam systemd, file unit layanan yang ditambahkan administrator seperti itu /etc/systemd/system/biasanya masuk (atau /usr/local/lib/systemd/system/jarang). Dengan manajer layanan nosh, /var/local/sv/adalah tempat konvensional untuk bundel layanan lokal. Mewburn rcpada penggunaan FreeBSD /usr/local/etc/rc.d/. File unit layanan yang dikemas dan bundel layanan, jika Anda membuatnya, pergi ke tempat yang berbeda.

Bacaan lebih lanjut

JdeBP
sumber
2
@LucianoAndressMartini Pertanyaan yang lebih baik adalah bagaimana menangani potongan tertentu rc.local dalam layanan systemd. Jadi, jika Anda memiliki cuplikan spesifik dalam pikiran (Anda menyebutkan instruksi dari beberapa dokumentasi perangkat lunak), mungkin memposting pertanyaan tentang itu? Ada aturan umum tertentu yang dapat digunakan untuk konversi, tetapi Anda mendapatkan lebih banyak darinya dengan mengeksploitasi fitur perangkat lunak yang Anda jalankan (seperti berjalan di latar depan, tidak mencoba untuk mengubah bentuk, dll.) Jadi bertanya tentang kasus tertentu mungkin bermanfaat.
filbranden
4
Anda harus bertanya-tanya apakah itu selamat dari penghinaan sejak tahun 1983, mungkin ada sesuatu yang terjadi untuk itu?
dan carter
4
Jawaban ini berkhotbah dan gagal untuk benar-benar hanya menjawab pertanyaan sederhana "hal sepele apa yang harus saya lakukan sebagai gantinya". Ini mungkin berisi informasi, dan memberikan banyak referensi, tetapi mengalahkan tujuan dari stackexchange.
gps
Saya membawa ini (akhir dari rc.local), bersama-sama dengan dns menyelesaikan masalah, sebagai alasan mengapa linux tidak berkembang, tetapi sebenarnya semakin menjadi kode spaghetti semakin banyak, systemd telah menjadi kotak hitam bagi banyak orang. Jika seorang pengguna atau administrator ingin memasukkan sesuatu ke rc.local dan tidak lagi bisa, tidak ada gunanya memaksa mereka untuk terlebih dahulu melakukan kursus systemd atau apa pun yang Anda khotbahkan untuk mencapai hasil akhir yang sama dalam hitungan hari, bukan menit. Tentu saja, orang idiot dapat melakukan hal-hal bodoh dengan segala sesuatu yang bekerja dengan baik dan mudah untuk dikerjakan, itu tidak pernah menjadi argumen yang valid untuk mengakhirinya.
Julius
2

Ringkasan https://www.linuxbabe.com/linux-server/how-to-enable-etcrc-local-with-systemd

Buat /etc/systemd/system/rc-local.service:

# /etc/systemd/system/rc-local.service
[Unit]
 Description=/etc/rc.local Compatibility
 ConditionPathExists=/etc/rc.local

[Service]
 Type=forking
 ExecStart=/etc/rc.local start
 TimeoutSec=0
 StandardOutput=tty
 RemainAfterExit=yes
 SysVStartPriority=99

[Install]
 WantedBy=multi-user.target

Kemudian:

sudo touch /etc/rc.local
sudo chmod +x /etc/rc.local
sudo systemctl enable rc-local

Periksa dengan:

sudo systemctl start rc-local.service
sudo systemctl status rc-local.service
Ole Tange
sumber
Penggunaan sistemd yang disediakan StandardOutput=journal+console(konsol setara dengan tty dalam contoh Anda), yang sepertinya akan jauh lebih berguna untuk pemecahan masalah. Dukungan untuk SysVStartPriority=telah dihapus di beberapa titik. Mungkin Anda bisa berkomentar betapa pentingnya SysVStartPriority=, atau menghapusnya. Terlepas dari itu, itu adalah jawaban yang layak.
sourcejedi