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 root:x:0:0:root:/root:/sbin/nologin so 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.)

Asked By: Wildcard

||

This happens because of less’s method of invoking commands specified in LESSOPEN or 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 lesspipe), 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 SHELL is 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 bash without -l, SHELL keeps whatever value it had previously.

(In fact, since less uses popen, the command run is sh -c "$SHELL" -c …)

Answered By: Stephen Kitt
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.