This information was presented to Seattle Xcoder's Eastside meeting on 4/27/2017 as a 15-minute "Lightning Talk."
As we move from viewing "standard" manual pages in a Unix terminal (not Mac-like) to viewing them in a much more readable Mac application—in this case, Preview.app—I'll highlight various Unix concepts and issues along the way.
Unix comes with a rather large body of online manual pages which are accessed from a Unix terminal window via the
command man
.
Hence the common name, "man pages," short for manual pages. Man pages have a common format describing all, or nearly
all aspected of the topic of the page.
Some man pages are highly focused on a given command whereas others are far more general, and can be quite long.
Furthermore, man pages are organized by "section," where certain kinds of information about a topic are found in
the general section.
The place to start learning about the features of man and how to use it is to open Terminal.app and enter:
man man
at the prompt. Your prompt will disappear and the screen will be filled with the manual page.
At this point, you will interact with the manual page viewer in ways that directly depend upon which man page viewer is employed.
By default, man man
is the same as entering man 1 man
where 1 is the most general, introductory
section for a topic.
Pay attention to the ordering: man 3 printf
will give you a manual page about the Unix C library function printf
whereas man printf 3
will ignore the 3rd parameter and just give you the section 1 manual page for printf
.
Here, how you navigate the manual page will depend upon how man
is configured to use
one of many possible ways to view the manual pages.
The viewers can be wildly different and sometimes behave in unexpected ways if you mistake one for another.
We'll cover a few of them here; we will not cover all of them.
By default, man
formats and opens the manual page contents with a text viewer called less
.
In the very beginning, there was cat
which simply concatenated, or wrote out, a file to the screen.
The whole man page just spilled out onto your screen without stopping;
no paging, no up or down scrolling—not terribly convenient.
As Unix matured, a better solution came along. This was more
which spilled out the contents of the man page
a page or screen at a time. Far better than cat
but it did not allow for backward scrolling of the pages.
Finally, more
was replaced by less
. Less
allows both forward- and backward-movement
within the file as it is displayed.
Slightly better.
But after years of reading proportionally spaced fonts, I find reading fixed-witdth fonts rather difficult and unnatural.
Add to that the fact that manual pages are written as if you already know Unix generally;
they are not written for the total neophyte.
Consequently, man pages can be very cumbersome to read let alone understand.
Hence, the desire to view them in a GUI app instead of in a Terminal window.
When both the presentation of content and navigation through that content are much more familiar, focus upon
and understanding of the content is facilitated.
To be honest, since I've been using Preview.app for man pages, I've found them much more enjoyable and informative
read.
Others may prefer reading man pages in vi
or emacs
text editors.
It really depends on what you are most comfortable with and what best compliments your workflow.
man
Tidbits
After you finish configuring man
the way you like, you may want to explore these topics:
man -k
or apropos
—search through man page decriptions for given string or word.man -K
—(NOTE: capital-k) search through ALL man page content for a given string or word. This may take
a long time.man bash
—learn more than you ever wanted to know about bash
, the default Unix shell.man intro
—introduction to general commands and utilities.whatis intro
—lists the "intro" topics in each section of the man database.man
sometimes contains a description of each section;
the macOS version does not.
In other words, they are system dependent and can sometimes be wildly out of date.
One of the most powerful features of Unix is the "pipe." This is the ability to take the output of one program and use it as input, or "pipe it," to another program. In this manner, one can construct a complex sequence of file manipulations that would be difficult and cumbersome to achieve otherwise. This is facilitated by the existence in 3 standard Unix data streams available to all Unix programs:
stdin
—the input stream. When you type in a Terminal window, the keyboard is the input stream.
When you print a file, the contents of the file itself is the input stream.stdout
—the output stream. When you type in a Terminal window, the screen is the output stream.
When you print a file, the formatted content sent to the printer is the output stream.stderr
—error stream. Any errors encountered are directed to this stream which may be also
diverted to the output stream. In a Terminal window, errors are diverted to the output stream.
When you issue the command to print a file, any errors in processing the file are sent to the terminal window and
not to the printer.
In bash
, as well as every other Unix shell, the pipe command is represented by "|".
man
Before more
, less
, and the enhanced ability to format man pages we have today,
it was common to use pipes to format a man page to plain text, saving it to a file. This could then
be opened with your favorite Unix text editor:
man 7 intro | col -bx > intro7_man.txt
Here, the > symbol is a file redirector telling the output of col
piped to the file system as input for the file intro7_man.txt
.
Then the file can be opened and read with a text editor, in this case vi
:
vi intro7_man.txt
Still cumbersome, even if you opened that file with Preview because col -bx
strips out most formatting characters.
One remedy for this sad state of affairs is the environment variable MANPAGER
.
When this environment variable is absent, the default behavior would be as if one entered:
man 7 intro | /usr/bin/less -is
and we're back to less
.
To set this explicitly, you would add:
export MANPAGER="/usr/bin/less -is"
to your .bash_profile
file in your home directory (more on that in a bit).
If you prefer to use vi
or vim
(they are the same on macOS), you could set MANPAGER
to:
export MANPAGER=/bin/sh -c \"col -b | vim -c 'set ft=man ts=8 sw=4 nomod nolist nonu noma' -\""
This runs a new shell (within your existing one) with the command string between " and " as if you typed it into the command shell yourself.
The specified command takes the output of man
and pipes it into col
to remove formatting.
It then pipes that output to the vim
editor with a set of parameters to enable read-only viewing in vim
.
When you quit vim
, the shell exits, returning you to the shell where you issued the man
command.
Spiffy, but still, "so last century!"
Returning to the man page for man
, we find there is a parameter -t
that formats a manual page for .PDF
output which can then be further passed to groff
for further processing.
We would then enter
man -t printf
Furthermore the man page states the -t
option calls /usr/bin/groff -Tps -mandoc -c
where -Tps
says format the output for Postscript, -mandoc
says to expect mandoc format as input
and -c
says not to use color specifications in the output stream.
While the man page states man -t printf
calls /usr/bin/groff -Tps -mandoc -c
, it implies using one was
the same as using the other. But they are not the same. Let's see for ourselves.
If you set
export MANPAGER="/usr/bin/groff -Tps -mandoc c"
you will find that you don't get bolding, underlining, paging, etc. and it's not quite right where letters in headings overlap
and not really readable.
To fix that, you'd have to set
export MANPAGER="col -bx | /usr/bin/groff -Tps -mandoc c"
where col
strips out the formatting to get readable output.
Okay, but without the nice formatting we're really looking for.
"Close, but no cigar," as the man at the circus used to say.
Turning to the man
source code, available here https://opensource.apple.com/source/man/man-16/
(you have to root around a bit to figure out what's actually being done),
you will eventually find that in man.c
, the rountine make_nroff_command
function is prepending and appending specific Postscript page and line commands to the
output stream it sends to groff
. <gak!>
So we're back to man -t
.
What macOS app reads PDF?
Preview.app, of course. But how do we get Preview to read stdout
from another program as stdin
for its input?
For this we turn to the open
command.
You may want to do a man open
at this point to see for yourself what is available there.
By the way, open
is very useful when going from your directory location in a terminal window to a Finder window.
Simply enter open .
and the Finder opens a window at that directory location.
With this knowledge, we can now use the command line
man -t man | open -f -a Preview.app
and our beloved man
man page opens beautifully formatted in Preview.
The last part of this journey is to be able to use the MANPAGER
environment variable to do the same thing.
How do you get the command parameters to MANPAGER
?
The answer is to pass the command parameters along. You do this with "$@"
, thusly:
export MANPAGER="man -t "$@" | open -f -a Preview.app"
Finally, to make this a part of your command shell, two lines need to be added to your .bash_profile
.
function preview_man () { man -t $@ | open -f -a Preview.app; }
alias pm = preview_man
pm
will be your new command alias to execute the function preview_man
.
Here are the steps to do this:
cd ~
or cd $HOME
to get to hour home directory.vim .bash_profile
to open or create that file (it may not exist).vim
, so perhaps do a man vim
before beginning
the edit session—or—once in vim
enter :h
to enter its help and
:q
to exit its help.):wq
in vim
to save and quit it.
.bash_profile
settings.pm man
or pm intro
instead of using man
.
Badda–Bing! Badda–Boom! ... Not your father's man pages!