/sleep
Angenommen, ich möchte, dass mein Server bei jeder HTTP-Anforderung an den Pfad (also ) in den Ruhezustand wechselt http://hostname/sleep
, aber vor dem Ruhezustand auch eine vollständige Antwort ( HTTP 200
) sendet.
Verwenden vonnginxmitFastCGI, ich habe den Pfad in dernginxAufbau:
location /sleep {
fastcgi_pass unix:/path/to/fcgiwrap.socket;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /path/to/script.sh;
}
Dies ruft das folgende Skript auf ( /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 &
Auch wenn das System dadurch in den Ruhezustand versetzt wird,FastCGIblockiert, bis der untergeordnete Prozess abgeschlossen ist, was bedeutet, dass die Webanforderung nicht abgeschlossen wird, bevor das System in den Ruhezustand versetzt wird. Wie kann ich also diesen letzten Befehl von der Überwachung trennen, indem ichFastCGIsodass die Antwort abgeschlossen wird, der Befehl jedoch im Hintergrund fortgesetzt wird, in diesem Fall, um das System letztendlich in den Ruhezustand zu versetzen?
Antwort1
Sie können das CGI und das Suspend entkoppeln, indem Sie eine Datei einfügen, die als systemd-Trigger verwendet wird. Siehe man systemd.path
hierzu die pfadbasierte Aktivierung einer Einheit. Dies hat den Vorteil, dass Sie vom CGI aus kein sudo verwenden müssen.
Erstellen einer Unit-Datei/etc/systemd/system/mycgitrigger.path
[Path]
PathModified=/some/writeable/file
[Install]
WantedBy=multi-user.target
und aktivieren Sie es. Ändern Sie das CGI-Skript so, dass es einfach irgendetwas in die Datei schreibt, /some/writeable/file
um das Herunterfahren auszulösen. Legen Sie den kurzen Timeout- und Herunterfahrbefehl in eine Unit-Datei
/etc/systemd/system/mycgitrigger.service
(die nicht aktiviert werden muss).
Antwort2
Die naheliegende Lösung wäre
echo "sleep 1 && sudo systemctl suspend" | at now