Bug 289245 - usr.bin/man: support -l option
Summary: usr.bin/man: support -l option
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: 16.0-CURRENT
Hardware: Any Any
: --- Affects Some People
Assignee: Dag-Erling Smørgrav
URL: https://reviews.freebsd.org/D52385
Keywords:
: 290911 (view as bug list)
Depends on:
Blocks:
 
Reported: 2025-09-01 22:04 UTC by Ingo Schwarze
Modified: 2025-11-10 15:53 UTC (History)
8 users (show)

See Also:
des: mfc-stable15+
des: mfc-stable14+
des: mfc-stable13+


Attachments
support -l in usr.bin/man/man.sh (3.08 KB, patch)
2025-09-01 22:04 UTC, Ingo Schwarze
no flags Details | Diff
rebased to head, allow -lt, reject -Kl (3.98 KB, patch)
2025-09-03 15:33 UTC, Ingo Schwarze
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ingo Schwarze 2025-09-01 22:04:07 UTC
Created attachment 263402 [details]
support -l in usr.bin/man/man.sh

While it is generally not advisable to format manual pages at software build time and manual pages should instead normally be installed unformatted, in man(7) or mdoc(7) source form, some software packages, for a variety of reasons, do have a need to format a manual page at build time, which raises the question which command packages should use for that purpose if they want their build system to be as portable as possible.  The traditional way to format a manual page, of course, is by running the nroff(1) command, but some operating systems (for example, OpenBSD and some Linux distros using mandoc by default) no longer install groff(1) by default.  While running mandoc(1) would work on FreeBSD and most other *BSDs, many Linux distros and most commercial Unixes do not install mandoc by default.  Some software packages run commands like "man ./manpage.1" (notice the ./ in that command), a quirky syntax that was never supported by traditional Unix nor by any version of the CSRG's BSD.  Because that syntax has been supported by man-1.5 (formerly often used in Linux) since at least 1998 and by man-db (nowadays normally used on Linux) since at least 2001, it is fairly portable (and also supported by FreeBSD and NetBSD, but no longer by OpenBSD).  This syntax has many problems: it is ambiguous (some manual page names do contain slashes, for example about a dozen in FreeBSD), it is very confusing because  "man ./manpage.1" and "man manpage.1" have different meaning, which is highly counter-intuitive, it is arguably too magical and unclear because it relies too much on guessing what the user may mean rather than doing what the user says, and it is hard to document.  For details, see the recent discussion on the man-db mailing list starting at https://lists.nongnu.org/archive/html/man-db-devel/2025-08/msg00012.html .

In any case, the result of that discussion was that the maintainers of all widely-used man(1) implementations and all widely-used manual page formatters agreed that "man ./manpage.1" is an ill-designed syntax - specifically, Colin Watson (man-db), G. Branden Robinson (groff), and myself (mandoc).  So using that syntax should not be recommended to people writing portable build systems.

All three of us also agree that the syntax "man -l manpage.1" that has been supported by man-db for about two decades and by the mandoc implementation of man(1) for about one decade is better designed, unambigous, and is easy and straightforward to document, so we would like to start recommending that syntax for portable build systems.

Consequently, i think that it would be valuable if the man(1) implementation of FreeBSD, which is not only the most widely used *BSD system, but sees even more users because macOS also relies on it, would support -l.  The attached patch implements and documents it.

Some remarks regarding the patch and the surrounding code:
 * It is important that -l is mutually exclusive with -f and -k.  Combining it with -w has no value; with man-db, "man -lw" just prints the argument(s); with mandoc, -lw does the same as just -l.  In the FreeBSD logic, it's probably best to treat -l and -w as mutually exclusive.  I fail to see the reason why -t needs to be mutually exclusive with all these option; nonetheless, for consistency, my patch makes -l and -t mutually exclusive, just like -fkw and -t.
 * With the growing size of the set of mutually exclusive options, the triangular scheme of detecting and reporting clashes starts to look ugly, but i refrained from mixing any refactoring into this patch.
 * If -l support is added, i think support for "man ./manpage.1" should probably be kept for a few years to ensure a smooth transition.  After that, a decision can be made to either delete support for "man ./manpage.1" or to keep it for good - either way, that is out of the scope of this patch.

You are free to use this patch under the license already at the top of the file man.sh.
If you want to credit the author, that is Ingo Schwarze <schwarze@openbsd.org>, but i do not insist on being credited, this is not a particularly large or difficult patch.
Comment 1 Ed Maste freebsd_committer freebsd_triage 2025-09-02 16:36:22 UTC
I haven't yet reviewed the patch but this sounds good to me.

> * If -l support is added, i think support for "man ./manpage.1" should probably be
> kept for a few years to ensure a smooth transition.  After that, a decision can be
> made to either delete support for "man ./manpage.1" or to keep it for good - either
> way, that is out of the scope of this patch.

IMO we should start emitting a warning on `man ./manpage.1` usage indicating that it's deprecated, suggesting -l. But indeed that can happen after and independent of this change.
Comment 2 Mark Linimon freebsd_committer freebsd_triage 2025-09-03 05:53:24 UTC
^Triage: now that Attachments have a patch flag, the [patch] usage is obsolete.
Comment 3 Dag-Erling Smørgrav freebsd_committer freebsd_triage 2025-09-03 13:19:27 UTC
imo -t should be allowed with -l and ignored with -fkw, but we can deal with that separately.

Ingo, your patch appears to be against FreeBSD 13.0.  Any chance you could rebase it to something a little more recent, preferably main?
Comment 4 Ingo Schwarze 2025-09-03 15:33:08 UTC
Created attachment 263449 [details]
rebased to head, allow -lt, reject -Kl

des@> Ingo, your patch appears to be against FreeBSD 13.0.  Any chance you could rebase it to something a little more recent, preferably main?

Oops, my git clone of FreeBSD was still on branch master, and i failed to realize that's an obsolete branch because i don't use the clone very often.  Sorry for that, i now checked out main, pulled, and rebased the patch.

des@> imo -t should be allowed with -l

Done in man-l.head.patch.

In man.1, i consequently moved -l to the -adhlo group.  I don't think it's important for the synopsis to alert the reader that -lw is not very useful, it's kind of obvious anyway from the meaning of the options.  Besides, the behaviour of different man(1) implementations varies for -lw, so not talking too much about it is maybe even an advantage.

des@> and ignored with -fkw, but we can deal with that separately.

Indeed, that's at most tangentially related, so changes made in this respect.
Comment 5 Ingo Schwarze 2025-09-03 16:20:40 UTC
At the end of the previous comment, i meant "so *no* changes made in this respect."

This comment mentions a few aspects that are not directly related to the patch and should be dealt with separately; i'm mentioning them here to reduce the risk that they are forgotten.

1. The option -t is an archaic way of asking for PostScript output that was mostly used in AT&T Research Unix from 1977 to 1989.  While man-db and Oracle Solaris still support -t, the modern way to select PostScript output is "-T ps", also because more people want "-T pdf" nowadays than PostScript.  Not sure what, if anything, should be done about that - i'm merely mentioning it FYI.  For details, see https://mandoc.bsd.lv/man/man.options.1.html .

2. In the mandoc implementation of man(1), the options -k and -w can be combined.  Saying -kw, you get the absolute pathnames of all manual pages files matched by the search, and i think that makes a lot of sense logically.  The man-db implementation of man(1) rejects -kw just like FreeBSD though.  Again, just FYI.

3. In the mandoc implementation of man(1), -l overrides -w, so -lw does the same as -l and ignores -w.  In man-db, -lw simply prints out the arguments, one per line.  Just FYI, none of these behaviours is particularly useful.
Comment 6 Dag-Erling Smørgrav freebsd_committer freebsd_triage 2025-09-04 17:51:11 UTC
I added a warning: https://reviews.freebsd.org/D52385
Comment 7 commit-hook freebsd_committer freebsd_triage 2025-09-07 20:53:34 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=14b61b2e931741281d0bfef426e9809f16006504

commit 14b61b2e931741281d0bfef426e9809f16006504
Author:     Ingo Schwarze <schwarze@usta.de>
AuthorDate: 2025-09-07 20:52:09 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2025-09-07 20:52:09 +0000

    man: Add -l option

    Add a -l option which causes man to interpret all arguments as paths to
    open directly rather than man pages to search for in MANPATH.  See the
    PR for a detailed rationale.

    PR:             289245
    MFC after:      1 week
    Reviewed by:    ziaee, emaste
    Differential Revision:  https://reviews.freebsd.org/D52385

 usr.bin/man/man.1  | 24 ++++++++++++++++++------
 usr.bin/man/man.sh | 33 ++++++++++++++++++++++++---------
 2 files changed, 42 insertions(+), 15 deletions(-)
Comment 8 Wolfram Schneider freebsd_committer freebsd_triage 2025-09-08 10:17:43 UTC
Is there a reason why the new flag '-l' was not added to the usage message?

freebsd-src/usr.bin/man/man.sh -h
Usage:
man [-adho] [-t | -w] [-M manpath] [-P pager] [-S mansect]
[-m arch[:machine]] [-p [eprtv]] [mansect] page [...]
man -K | -f | -k expression [...] -- Search manual pages
Comment 9 commit-hook freebsd_committer freebsd_triage 2025-09-08 13:28:06 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=dc38cf116c820df0be341ec5e359de0012b2d58a

commit dc38cf116c820df0be341ec5e359de0012b2d58a
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2025-09-08 13:26:43 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2025-09-08 13:27:34 +0000

    man: Fix usage message

    PR:             289245
    Fixes:          14b61b2e9317 ("man: Add -l option")

 usr.bin/man/man.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Comment 10 Wolfram Schneider freebsd_committer freebsd_triage 2025-09-16 05:07:41 UTC
`man -w /full/path/manpage' reports now a warning:

freebsd-src/usr.bin/man/man.sh -w /usr/share/man/man1/man.1.gz
Opening a file directly is deprecated, use -l instead.
/usr/share/man/man1/man.1.gz

I do not want open a file, I just want to know the location.

I think that calling man -w with a full path is a valid use case.
Comment 11 commit-hook freebsd_committer freebsd_triage 2025-09-16 13:59:16 UTC
A commit in branch stable/15 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=668fbde7df9af6e78cef7e9f5fa8ec7cb0966119

commit 668fbde7df9af6e78cef7e9f5fa8ec7cb0966119
Author:     Ingo Schwarze <schwarze@usta.de>
AuthorDate: 2025-09-07 20:52:09 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2025-09-16 13:05:52 +0000

    man: Add -l option

    Add a -l option which causes man to interpret all arguments as paths to
    open directly rather than man pages to search for in MANPATH.  See the
    PR for a detailed rationale.

    PR:             289245
    MFC after:      1 week
    Reviewed by:    ziaee, emaste
    Differential Revision:  https://reviews.freebsd.org/D52385

    (cherry picked from commit 14b61b2e931741281d0bfef426e9809f16006504)

 usr.bin/man/man.1  | 24 ++++++++++++++++++------
 usr.bin/man/man.sh | 33 ++++++++++++++++++++++++---------
 2 files changed, 42 insertions(+), 15 deletions(-)
Comment 12 commit-hook freebsd_committer freebsd_triage 2025-09-16 14:00:18 UTC
A commit in branch stable/14 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=61735a4f685bb1a1d2a787d79e1541ed017a5ca5

commit 61735a4f685bb1a1d2a787d79e1541ed017a5ca5
Author:     Ingo Schwarze <schwarze@usta.de>
AuthorDate: 2025-09-07 20:52:09 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2025-09-16 13:05:54 +0000

    man: Add -l option

    Add a -l option which causes man to interpret all arguments as paths to
    open directly rather than man pages to search for in MANPATH.  See the
    PR for a detailed rationale.

    PR:             289245
    MFC after:      1 week
    Reviewed by:    ziaee, emaste
    Differential Revision:  https://reviews.freebsd.org/D52385

    (cherry picked from commit 14b61b2e931741281d0bfef426e9809f16006504)

 usr.bin/man/man.1  | 24 ++++++++++++++++++------
 usr.bin/man/man.sh | 33 ++++++++++++++++++++++++---------
 2 files changed, 42 insertions(+), 15 deletions(-)
Comment 13 commit-hook freebsd_committer freebsd_triage 2025-09-16 14:00:19 UTC
A commit in branch stable/13 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=e5c5d8f78eade3a78825caf395c86fb9e7dccc82

commit e5c5d8f78eade3a78825caf395c86fb9e7dccc82
Author:     Ingo Schwarze <schwarze@usta.de>
AuthorDate: 2025-09-07 20:52:09 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2025-09-16 13:55:22 +0000

    man: Add -l option

    Add a -l option which causes man to interpret all arguments as paths to
    open directly rather than man pages to search for in MANPATH.  See the
    PR for a detailed rationale.

    PR:             289245
    MFC after:      1 week
    Reviewed by:    ziaee, emaste
    Differential Revision:  https://reviews.freebsd.org/D52385

    (cherry picked from commit 14b61b2e931741281d0bfef426e9809f16006504)

 usr.bin/man/man.1  | 25 ++++++++++++++++++++-----
 usr.bin/man/man.sh | 31 +++++++++++++++++++++++--------
 2 files changed, 43 insertions(+), 13 deletions(-)
Comment 14 Dag-Erling Smørgrav freebsd_committer freebsd_triage 2025-09-19 11:04:56 UTC
(In reply to Wolfram Schneider from comment #10)
> I think that calling man -w with a full path is a valid use case.

Sure, you can do that, as long as you also pass the -l option to skip the MANPATH search.  I don't see why you would though.
Comment 15 commit-hook freebsd_committer freebsd_triage 2025-09-23 12:58:37 UTC
A commit in branch stable/15 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=fd017bf5ef37e8e6cccc9e887d4fcc4c594b0602

commit fd017bf5ef37e8e6cccc9e887d4fcc4c594b0602
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2025-09-08 13:26:43 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2025-09-23 12:57:29 +0000

    man: Fix usage message

    PR:             289245
    Fixes:          14b61b2e9317 ("man: Add -l option")
    (cherry picked from commit dc38cf116c820df0be341ec5e359de0012b2d58a)

 usr.bin/man/man.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Comment 16 commit-hook freebsd_committer freebsd_triage 2025-09-23 13:07:41 UTC
A commit in branch stable/14 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=d13a8d09338d1825a3ae16e8e50f4686e88acbc4

commit d13a8d09338d1825a3ae16e8e50f4686e88acbc4
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2025-09-08 13:26:43 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2025-09-23 13:06:37 +0000

    man: Fix usage message

    PR:             289245
    Fixes:          14b61b2e9317 ("man: Add -l option")
    (cherry picked from commit dc38cf116c820df0be341ec5e359de0012b2d58a)

 usr.bin/man/man.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Comment 17 commit-hook freebsd_committer freebsd_triage 2025-09-23 13:07:42 UTC
A commit in branch stable/13 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=0416dd2d0330a451d2d558785deb84f0b5c36b40

commit 0416dd2d0330a451d2d558785deb84f0b5c36b40
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2025-09-08 13:26:43 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2025-09-23 13:06:14 +0000

    man: Fix usage message

    PR:             289245
    Fixes:          14b61b2e9317 ("man: Add -l option")
    (cherry picked from commit dc38cf116c820df0be341ec5e359de0012b2d58a)

 usr.bin/man/man.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Comment 18 Ingo Schwarze 2025-09-23 15:40:30 UTC
(In reply to Wolfram Schneider from comment #10)

Hello Wolfram,

in addition to what des@ said in comment #14, here are some
additional thoughts:

1. If the desired output is /full/path, then
   echo /full/path
   does the trick, and it is hard to see why man(1) should duplicate the functionality.

2. If you want to normalize a relative to an absoulte path,
   cd /full; realpath ./path
   does it, and while realpath(1) is not in POSIX, it is widely available,
   and again it is hard to see why man(1) should duplicate,
   in particular since such functionality in man(1) would not be portable:

2.1. With man-db, both of
     man -w ./path
     man -lw ./path
     print "./path", not the absolute path.

2.2. With the mandoc implementation of man(1), it has been documented for several years that -l causes -w to be ignored, so both "man -lw" and "man -wl" are the same as "man -l".

2.3. In FreeBSD, -l and -w are now mutually exclusive, which is possibly the most reasonable solution given that the behaviour of other implementations is neither consistent nor useful.

On a separate note, thanks for catching the usage() oversight and to des@ for fixing it.
Comment 19 Ed Maste freebsd_committer freebsd_triage 2025-11-10 15:53:51 UTC
*** Bug 290911 has been marked as a duplicate of this bug. ***