less, sudo, and /dev/null: Permission denied
Sigh. The ubiquitous utility less does a really bad and hard to understand
thing. For some time now, it behaves not just as a reader but also a writer:
it writes a history file (specified by the environment variable
$HOME/.lesshst by default). If you want less to be writing
things, fine, but don't force it on me! This has caused some annoying
problems that have been really hard to finally trace back to less.
To turn off this behavior, set the variable
LESSHISTFILE (either in the
environment or in your lesskey file) to
'-'. The docs say you can use
'/dev/null' too, but don't-- I'll explain below. Besides writing a file,
less goes a step further and does a chmod on that file to
0600, which is
actually a reasonable permission set to keep others from seeing your history.
The problem is that
sudo picks up the
HOME variable but not
sudo less was writing a
.lesshst file in my home
Some time ago, I gakked and disgustedly symlinked .lesshst to /dev/null. But
then when less does the chmod during sudo, it changes the permissions of
/dev/null (which is why LESSHISTFILE set to /dev/null is bad-- less is
supposed to ignore it in that case but still somehow chmods /dev/null). So I
couldn't use /dev/null anymore (and quite a few scripts do so, it's a standard
practice), getting messages like
/dev/null: Permission denied.
The workaround to this
bug 'feature' of less is to set the
LESSHISTFILE variable in the
LESSKEY file (
% lesskey - #env LESSHISTFILE = - ^D
then sudo will pick up
$HOME, less will then read
$HOME/.less and not create the stoopid
.lesshst, so I don't need the symlink
There are other reports of changing permissions on
/dev/null that are
generally unexplained. Try to stay away from symlinks to
/dev/null in your
home directory, especially any that might get chmod applied by a program you
run via sudo. (I still have
.recently-used symlinked to
/dev/null. I don't think I sudo anything using those...)
Jesper commented at 2011-06-01 07:22:06
Interesting, thanks for the analysis. I just stumbled on this problem myself.
$ export LESSHISTFILE=/dev/null $ sudo -s # history|less (or any other invocation of less I guess) *poof* /dev/null is 700, thus unusable for non-root users.
I guess the sudo -s carried over the LESSHISTFILE variable to the privileged shell, and less got a bit too eager about permissions on what it believed to be its history file.