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
pagerand have the environment variablesLESS=FRX,MORE=FRXandLV=Csuch that it picks up your preferred pager; and then sets up the default.For the auto-paging,
Fis important (so it doesn't page when it fits on the screen) andXis 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 specifycatas 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
stdinto/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.