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.
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.
^Triage: now that Attachments have a patch flag, the [patch] usage is obsolete.
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?
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.
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.
I added a warning: https://reviews.freebsd.org/D52385
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(-)
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
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(-)
`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.
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(-)
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(-)
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(-)
(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.
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(-)
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(-)
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(-)
(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.
*** Bug 290911 has been marked as a duplicate of this bug. ***