Действительно, всё перечисленное ниже можно сделать с помощью acpid. И да, так было бы гораздо лучше. Но мне хотелось размять буйну голову, да соорудить миленький велосипедик. Зато свой. И еще одно уточнение – на моём системном блоке есть только кнопка Power.
Итак, написана была маленькая программка на C, которая делает только одну вещь: выполняет команду при нажатии кнопки Power на системном блоке.
В Unix всё – файл, а поэтому можно читать сообщения с “файлов” устройств. Что и было использовано. Необходимо только определить: какой файл в папке /dev относится к кнопке выключения. Можно даже сузить поиски: какой файл из event в папке /dev/input. Я лично просто перебрал всё что было в этой директории по очереди командой:
$ cat /dev/input/event0
При нажатии кнопки Power должен появляться мусор в консоли (и только тогда). Теперь можно и написать программку:
#include <linux/input.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> int main (int argc, char **argv){ int file_descriptor; int read_result; struct input_event event; if (argc < 3) { printf("Использование: buttond /dev/input/eventX \"Y\"\n"); printf("Где X = номер устройства ввода кнопки питания\n"); printf(" Y = команда\n"); exit(EXIT_FAILURE); } if ((file_descriptor = open(argv[1], O_RDONLY)) < 0) { printf("Невозможно открыть устройство\n"); exit(EXIT_FAILURE); } while(1){ read_result = read(file_descriptor, &event, sizeof(struct input_event)); if (read_result != sizeof(struct input_event)) { printf("Ошибка считывания данных с устройства кнопки питания\n"); exit(EXIT_FAILURE); } else { /*event.value = 1, если кнопка нажата, 0 - кнопку отпустили*/ if(event.code == KEY_POWER && event.value == 1){ system(argv[2]); exit(EXIT_SUCCESS); } } } }
Компилируется она просто (если эти строки скопировать в файл с именем button.c):
$ gcc button.c -o powerbuttond
Затем необходимо переместить программку в какую-нибудь root’овскую папку с бинарниками:
# mv powerbuttond /usr/sbin/
Окончательно протестировать работу можно вот так:
# powerbuttond /dev/input/event1 "ls -a -l"
Если всё работает, то осталось только написать скрипт для systemd или SysVinit (мой случай):
case ${1} in start) powerbuttond /dev/input/event1 "/sbin/halt" & ;; stop) killall powerbuttond ;; *) echo "Usage: ${0} {start|stop}" exit 1 ;; esac exit 0
Заменив /sbin/halt на команду отключения, которая вам по душе.
Ваш комментарий будет первым