Automatically paging output from a command line tool through a
pager such
as less
. Popularized
by the git
version control system, it is now present and default in many
modern command line tools. The observation is that — unless
redirecting output to a file or pipe — users typically want to
view multi-page output in a pager. A command line tool that
supports auto-paging, will detect when stdout
is
a terminal, spawn a pager implementation and redirect its
output through that for convenience. To disable auto-paging,
many tools support a --no-pager
option, but it is
also always possible the pipe the output
through cat
.
Recommendations
from Julian Andres
Klode, who added auto-paging support to
Debian's apt
tool:
We always invoke
pager
and have the environment variablesLESS=FRX
,MORE=FRX
andLV=C
such that it picks up your preferred pager; and then sets up the default.For the auto-paging,
F
is important (so it doesn't page when it fits on the screen) andX
is questionable (it keeps the output around after you exit the pager)Special care is taken to allow overriding the pager with
APT_PAGER
,PAGER
; and of course if you specifycat
as a pager you need to disable paging.The complex bits are in launching the pager and making sure the pager is launched; particularly
- a pipe needs to be used to communicate readiness (set cloexec, after exec in the child() a read in the parent returns; if exec fails write errno to it)
- the pipe only works if you don't fork a shell, so detect when shell is needed.
Also don't forget to redirect
stdin
to/dev/null
(or a half-closed pipe) such that the piped process can't wait onstdin
.Then you also need to do a whole bunch of signal handler stuff which is quite annoying.
It really adds up to a couple hundred lines of code.
The auto-pager implementation in git
is here.
The systemd implementation is also a good reference,
available here.