Saya memiliki layanan yang menjalankan perangkat lunak yang menghasilkan beberapa file konfigurasi jika tidak ada, dan membacanya jika ada. Masalah yang saya hadapi adalah file-file ini terkadang rusak, membuat perangkat lunak tidak dapat memulai, dan dengan demikian membuat layanan gagal. Dalam hal ini saya ingin menghapus file-file ini dan memulai kembali layanan.
Saya mencoba membuat layanan yang harus dijalankan jika terjadi kegagalan, dengan melakukan ini:
[Service]
ExecStart=/bin/run_program
OnFailure=software-fail.service
di mana layanan ini:
[Service]
ExecStart=/bin/rm /file/to/delete
ExecStop=systemctl --user start software.service
Masalahnya, bagaimanapun, adalah bahwa layanan ini tidak dimulai, bahkan ketika layanan gagal.
Saya mencoba melakukannya
systemctl --user enable software-fail.service
tetapi kemudian dimulai setiap kali sistem dimulai, sama seperti layanan lainnya.
Solusi sementara saya adalah menggunakan
ExecStopPost=/bin/rm /file/to/delete
tetapi ini bukan cara yang memuaskan untuk menyelesaikannya, karena akan selalu menghapus file setelah menghentikan layanan, tidak peduli apakah itu karena kegagalan atau tidak.
Keluaran saat gagal:
● software.service - Software
Loaded: loaded (/home/trippelganger/.config/systemd/user/software.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Fri 2018-05-04 09:05:26 CEST; 5s ago
Process: 1839 ExecStart=/bin/run_program (code=exited, status=1/FAILURE)
Main PID: 1839 (code=exited, status=1/FAILURE)
May 04 09:05:26 trippelganger systemd[595]: software.service: Main process exited, code=exited, status=1/FAILURE
May 04 09:05:26 trippelganger systemd[595]: software.service: Unit entered failed state.
May 04 09:05:26 trippelganger systemd[595]: software.service: Failed with result 'exit-code'.
Output dari systemctl –user status software-fail.service
adalah:
● software-fail.service - Delete corrupt files
Loaded: loaded (/home/trippelganger/.config/systemd/user/software-fail.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Jawaban yang Diterima:
CATATAN :Anda mungkin ingin menggunakan ExecStopPost=
bukannya OnFailure=
di sini (lihat jawaban saya yang lain), tetapi ini mencoba mengatasi mengapa OnFailure=
Anda penyiapan tidak berfungsi.
Masalah dengan OnFailure=
tidak memulai unit mungkin karena berada di bagian yang salah, itu harus di [Unit]
bagian dan bukan [Service]
.
Anda dapat mencoba ini sebagai gantinya:
# software.service
[Unit]
Description=Software
OnFailure=software-fail.service
[Service]
ExecStart=/bin/run_program
Dan:
# software-fail.service
[Unit]
Description=Delete corrupt files
[Service]
ExecStart=/bin/rm /file/to/delete
ExecStop=/bin/systemctl --user start software.service
Saya dapat membuatnya bekerja dengan pengaturan ini.
Tetapi perhatikan bahwa menggunakan OnFailure=
tidak ideal di sini, karena Anda tidak dapat benar-benar mengetahui mengapa program gagal, dan merantai awal yang lain di ExecStop=
dengan memanggil /bin/systemctl start
langsung cukup hacky… Solusinya menggunakan ExecStopPost=
dan melihat status keluar pasti lebih unggul.
Jika Anda mendefinisikan OnFailure=
di dalam [Service]
, systemd (setidaknya versi 234 dari Fedora 27) mengeluh dengan:
software.service:6: Unknown lvalue 'OnFailure' in section 'Service'
Tidak yakin apakah Anda melihatnya di log atau tidak… (Mungkin ini ditambahkan di systemd baru-baru ini?) Itu seharusnya menjadi petunjuk tentang apa yang terjadi di sana.
Terkait:Perbedaan antara '>' dan '-gt'?