Условное отключение Ctrl-Alt-Del

Вопрос или проблема

Я всегда выключаю свои Linux с помощью Ctrl-Alt-Del. Теперь я хочу, чтобы система все еще выключалась с помощью Ctrl-Alt-Del, но только если определенное УСЛОВИЕ выполнено. (Это условие — наличие файла.)

Что-то вроде этого:

#!/bin/bash

if [[ ! УСЛОВИЕ ]]; then

    echo
    echo "  *************************"
    echo "  *************************"
    echo "  **                     **"
    echo "  **   НЕПРАВИЛЬНОЕ УСЛОВИЕ   **"
    echo "  **                     **"
    echo "  *************************"
    echo "  *************************"
    echo
else
    sudo shutdown -h now
fi

Я думаю, что могу сделать что-то с сервисом/целевым объектом, но у меня совершенно ничего не вышло….

Два общих подхода к решению этой задачи (к сожалению, ваш не подходит ни под один из них!):

  1. (легкий) вы пишете программу, оболочку, что угодно, что завершает работу, как только УСЛОВИЕ выполняется. Вы вызываете эту программу с помощью systemd-inhibit --what=shutdown myblockingprogram. Поскольку вы не хотите выяснять, была ли она запущена ранее, и вам не нужно, чтобы был цикл, опрашивающий УСЛОВИЕ, в идеале это выполнение должно автоматически запускаться каким-то действием, которое вызывает уведомление.
    В вашем случае, где УСЛОВИЕ — “наличие файла”, это немного усложняется в оболочке. Но, конечно, у вас может быть цикл, который выполняет вышеуказанную команду после проверки наличия файла, с коротким sleep между проверками, чтобы не перегружать ядро процессора только для проверки. Более элегантно:
  2. (более общий) вы пишете свой собственный ингибитор выключения. Это подробно объясняется здесь, в официальной документации. Вы пишете программу (здесь недостаточно только оболочки; но python, C++, Go, Rust или C идеально подойдут, например), которая вызывает функциональность Inhibit(), что возвращает файловый дескриптор. В момент, когда вы закрываете этот файловый дескриптор, выключения снова начинают разрешаться.
    Итак, в этом сценарии вы используете inotify или fanotify, чтобы получать уведомления, когда целевой файл создается. Когда он создается, вы вызываете функциональность Inhibit и получаете файловый дескриптор. Вы используете inotify/fanotify, чтобы получать уведомления о том, что файл удален. Как только этот файл исчезает, вы закрываете файловый дескриптор. Вы запускаете эту программу автоматически как службу пользователя systemd или системную службу.

Ответ или решение

Условный завершение работы системы через Ctrl-Alt-Del в Linux

Вопрос, как использовать сочетание клавиш Ctrl-Alt-Del для завершения работы Linux-системы только при выполнении определенного условия, представляет интерес как для системных администраторов, так и для пользователей, желающих иметь дополнительный уровень контроля над процессом завершения работы. Давайте разберем, как можно реализовать такую функциональность, основываясь на двух подходах.

Подход 1: Простой скрипт с системной блокировкой

Этот метод предполагает написание простого скрипта, который будет проверять наличие файла (или другое условие) и блокировать завершение работы системы, если условие не выполнено. Вам понадобится использовать systemd для создания блокирующей программы.

  1. Создайте скрипт. Ниже представлена базовая структура скрипта на Bash:

    #!/bin/bash
    
    CONDITION_FILE="/path/to/your/file"
    
    if [[ ! -e $CONDITION_FILE ]]; then
       echo
       echo "  *************************"
       echo "  **   Неправильное условие  **"
       echo "  *************************"
       echo
       exit 1
    else
       sudo shutdown -h now
    fi

    Убедитесь, что путь к файлу установлен правильно, а также дайте вашему скрипту права на выполнение с помощью команды chmod +x your_script.sh.

  2. Создайте систему блокировок с помощью systemd-inhibit. Запустите этот скрипт с помощью systemd-inhibit для блокировки завершения работы. Например:

    systemd-inhibit --what=shutdown /path/to/your_script.sh
  3. Расписание проверки: Чтобы избежать постоянного опроса сервера, можно добавить в скрипт задержку, например, с помощью команды sleep, если это необходимо.

Подход 2: Создание собственного инкаторного приложения

Этот подход более универсален и предполагает использование возможностей systemd для создания инкаторной программы, которая будет реагировать на создание и удаление файла.

  1. Создайте программу. На языках, таких как Python, C++, Rust или любом другом, создайте программу, использующую API Inhibit(), чтобы заблокировать завершение работы системы. Пример на Python может выглядеть следующим образом:

    import os
    import systemd.inhibit
    
    CONDITION_FILE = '/path/to/your/file'
    
    def main():
       with systemd.inhibit.Inhibit('shutdown') as inhibit:
           while not os.path.exists(CONDITION_FILE):
               time.sleep(1)
    
    if __name__ == "__main__":
       main()
  2. Используйте inotify для слежения за файлом. Ваша программа должна использовать библиотеку inotify, чтобы следить за созданием и удалением указанного файла, и соответственно блокировать и разблокировать завершение работы:

    import inotify.adapters
    
    # Слушатель событий inotify
    i = inotify.adapters.Inotify()
    i.add_watch(CONDITION_FILE)
    
    for event in i.event_gen(yield_nones=False):
       print(event)
       # Логика для блокировки/разблокировки завершения работы
  3. Автозапуск программы. Запланируйте вашу программу на автоматический запуск с помощью системной службы systemd.

Заключение

Создание условий для завершения работы системы с помощью Ctrl-Alt-Del позволит вам более гибко управлять жизненным циклом вашей Linux-системы, предотвращая случайные выключения. Оба описанных подхода имеют свои сильные и слабые стороны, поэтому выберите тот, который наиболее соответствует вашим требованиям и уровню профессиональной подготовки.

При реализации данного решения учтите, что взаимодействие с системными уровнями требует внимательности и понимания используемых инструментов, чтобы предотвратить несоответствия и нарушения в работе системы.

Оцените материал
Добавить комментарий

Капча загружается...