Предположим, я хочу, чтобы мой сервер переходил в спящий режим при любом HTTP-запросе к пути /sleep
(т. е. http://hostname/sleep
), но также перед переходом в спящий режим отправлял полный ответ ( HTTP 200
).
С использованиемnginxсFastCGI, я настроил путь вnginxконфигурация:
location /sleep {
fastcgi_pass unix:/path/to/fcgiwrap.socket;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /path/to/script.sh;
}
Это вызывает следующий скрипт ( /path/to/script.sh
):
#!/bin/sh
# -*- coding: utf-8 -*-
cat << EOF
Content-Type: text/html
<html><head><title>Sleep</title><meta charset="UTF-8"></head>
<body><p>Sleep: $(date)</p></body></html>
EOF
sleep 1 && sudo systemctl suspend < /dev/null > /dev/null 2>&1 &
Даже если это приведет к спящему режиму системы,FastCGIбудет блокироваться до тех пор, пока не завершится дочерний процесс, что означает, что веб-запрос не будет завершен до того, как система уснет. Итак, как мне отсоединить эту последнюю команду от контроляFastCGIтак что ответ завершается, но команда продолжает выполняться в фоновом режиме, в данном случае в конечном итоге для перевода системы в спящий режим?
решение1
Вы можете разделить cgi и приостановку, вставив файл, используемый как триггер systemd. Смотрите man systemd.path
для этой активации на основе пути юнита. Это имеет преимущество в том, что не нужно использовать sudo из cgi.
Создать файл блока/etc/systemd/system/mycgitrigger.path
[Path]
PathModified=/some/writeable/file
[Install]
WantedBy=multi-user.target
и включите его. Измените скрипт cgi, чтобы он просто записывал что-либо в файл /some/writeable/file
для запуска выключения. Поместите команду короткого тайм-аута и выключения в файл юнита
/etc/systemd/system/mycgitrigger.service
(который не нужно включать).
решение2
Очевидным решением было бы
echo "sleep 1 && sudo systemctl suspend" | at now