Why does `less` show "This account is not available" when run on a file from a root login shell?
This is not really a problem, just a peculiarity that I’d like to understand.
If I get a root shell with
sudo bash -l and then run
less somefilename I get less only showing:
This account is currently not available.
(This isn’t shown as an error, it’s shown inside less as though it were the contents of the file.)
However if I use the same root shell from
sudo bash -l and run
cat somefilename | less then I see the actual contents of the file.
Also if I get a root shell with
sudo bash and skip the
-l and then run
less somefilename it will show the file’s contents.
Root’s login is disabled; the
/etc/passwd line is
sudo su - doesn’t work.
But, why should the
nologin entry make any difference to running
less on a file? And why does it only make a difference if
less is run directly on the file rather than also applying to less running on its stdin? And, why does this only happen with a
bash -l shell?
(This is on a CentOS 7 system.)
This happens because of
less’s method of invoking commands specified in
LESSCLOSE. If the
SHELL environment variable is set, it uses its value as the shell to use to run them.
Thus in your scenario, since
LESSOPEN is set (thanks to the use of
less runs the equivalent of
"$SHELL" -c …, and shows the result of that as the file contents (since that’s the expected behaviour with a
LESSOPEN pipe). Since
nologin, you see that command’s output.
With a default
lesspipe setup, the pipe isn’t used if
less is itself receiving its input from a pipe, which explains that behaviour.
SHELL is only set by login shells. If you run
SHELL keeps whatever value it had previously.
(In fact, since
popen, the command run is
sh -c "$SHELL" -c …)