Inspired by Winsomnia-ssh but works without python (just uses bash ans wsl).
dependencies: iproute2 systemd coreutils procps
This version doesn't work if the bash login shell is force killed (SIGKILL), since then the trap doesn't trigger and the process isn't killed. This can also not be fixed using PDEATHSIG because for some reason this makes the corresponding windows process survive
- Set Powershell path in
winsomnia-old.sh - Set (absolute WSL) path to
keep_awake.ps1inwinsomnia-old.sh - Add the line
source /path/to/winsomnia-old.shto your~/.bashrcor other shell initialization script.
- Set Powershell path in
winsomnia.sh - Set (absolute WSL) path to
keep_awake.ps1inwinsomnia.sh
Run:
source stay_awake.sh
my_script.py > out.txt 2>&1; exit
Instead of sourcing the script per-shell, you can run winsomnia.sh as a
long-running systemd service. This avoids spawning a powershell process per
shell session and survives shell exits cleanly.
-
Copy the service unit file (create
~/.config/systemd/user/winsomnia.serviceor/etc/systemd/system/winsomnia.service):[Unit] Description=Keep system awake while SSH clients are connected [Service] Type=simple ExecStart=/bin/bash /absolute/path/to/winsomnia.sh Restart=on-failure RestartSec=10s [Install] WantedBy=multi-user.target
-
Reload systemd and enable:
sudo systemctl daemon-reload sudo systemctl enable --now winsomnia.service -
Verify:
systemctl status winsomnia.service
Add the included winsomnia.nix module to your configuration:
# flake.nix (or configuration.nix)
imports = [ ./winsomnia.nix ];Then rebuild:
sudo nixos-rebuild switch --flake /etc/nixosThe module defines ssh-keepawake-keepalive.service as Type=simple, so the
bash loop and its backgrounded powershell child both live in the same cgroup
and are reaped cleanly when the service is stopped. Restart=on-failure keeps
the loop alive across transient failures.
Whenever a new shell is initialized, the script checks if it is inside an ssh session. If that is the case, a Powershell child process is started that sets the SetThreadExecutionState to ES_CONTINUOUS | ES_SYSTEM_REQUIRED. This state is active until the windows thread exits. Fortunately, the windows process will be killed when the corresponding linux process is killed (see here), which is done using the trap ... EXIT.