Setting $PAGER correctly
You would think that setting up a classical tool like more(1)
nowadays should not be too difficult.
Alas, the devil is in the details.
Up front, here are my requirements for a pager:
- If I just scroll through the output, it should behave like
cat(1)
. Consequently, it must not clear the screen and it must exit as soon as it reaches EOF. - It should display colour.
As much as I like to use POSIX utilities, more(1)
doesn't fit the bill because it is specified to print control characters as implementation-defined multi-character sequences.
Using non-standard switches like -R
in order to modify its behaviour seems pointless, so I opted for less(1)
instead.
Less has a couple of options to make it behave the way I want:
-E
- Causes
less
to automatically exit the first time it reaches end-of-file. -R
- ANSI "color" escape sequences are output in "raw" form.
First of all, I tested my changes using the line
$ PAGER='less -ER' git log --all
Interestingly, it did not seem to make a difference whether I used the -R
switch or not.
As it turns out, this is because unless it is already set, git
(and hg
likewise) add the environment variable LESS=FRX
when calling the pager.
You can use PAGER=env
to verify this.
This means that for testing, it's actually better to use
$ git log --all --color | less -ER
As an aside, git
and hg
also set another variable which must be for a pager that I don't know:
LV=-c
Another stumbling block came when I actually tried this on one of my macOS systems.
I had TERM
set to xterm
and output didn't appear at all if it was less than a screenful.
This turned out to be because xterm
's initialisation string switches to the alternate screen and clears it.
Since my requirement is to work like cat(1)
, I don't need the alternate screen for this purpose.
But I must admit that it's a nice feature when using vi(1)
, for example, so I don't want to change my TERM
setting to ansi
which doesn't have an alternate screen.
So the correct solution (which was already anticipated by git
) is to also pass the -X
option to less(1)
, causing it to ignore the terminal initialisation sequence.
And finally, unfortunately the meaning of the -c
option is reversed on OpenBSD to what POSIX specifies for more(1)
, and clearing the screen is the default behaviour for less(1)
on that platform.
So in order to make my .profile
work, I ended up using the code
if [ OpenBSD == "$(uname -s)" ] then PAGER='less -ERXc' else PAGER='less -ERX' fi export PAGER
Comments
Post a Comment