Today I was playing with inhibitor locks. I can create one of those running this in a terminal:
systemd-inhibit bash
While I leave that bash process open, shutdown will presumably be inhibited. Indeed, if I open other terminal and type systemctl poweroff I will get this informative message:
Operation inhibited by "bash" (PID 2013 "systemd-inhibit", user ntrrgc), reason is "Unknown reason".
Please retry operation after closing inhibitors and logging out other users.
Alternatively, ignore inhibitors and users with 'systemctl poweroff -i'.
Next, I wanted to show the error message it in a GUI instead, so I instructed bash to pipe and store the output of systemctl poweroff, like this:
output=$(systemctl poweroff 2>&1)
Then, suddenly, the computer shut down.
I tried calling it in many ways, but there was a constant: If systemctl's stdout was not a tty it always ignored any inhibitor locks. It did not matter it was piped to bash, to /dev/null or was running in a GUI outside of the terminal, in any case it did shutdown disregarding the locks. The locks where respected only when stdout was a virtual terminal.
Why does this happen? Can it be avoided?
if you have the priviliges to ignore inhibitors, then you can shutdown even if there's an inhibitor in place.
In order not to break scripts inhibitors are not shown if systemctl is called non-interactively – if the scripts has the priviliges to ignore the inhibitors. That's what you are seeing here.
This is expected behaviour hence.
Thanks for the explanation.
That's a bit unfortunate for use cases like this. Isn't there a way to tell systemctl to obey inhibitors anyway? Maybe it should be included in https://github.com/systemd/systemd/issues/949?
By the way, I could not find that behavior documented anywhere. I searched in man systemctl and found a --ignore-inhibitors switch but it does not specify it being a default for non-interactive executions.
Most helpful comment
Thanks for the explanation.
That's a bit unfortunate for use cases like this. Isn't there a way to tell systemctl to obey inhibitors anyway? Maybe it should be included in https://github.com/systemd/systemd/issues/949?
By the way, I could not find that behavior documented anywhere. I searched in
man systemctland found a--ignore-inhibitorsswitch but it does not specify it being a default for non-interactive executions.