1

Systems often have multiple versions of binaries and the one selected depends on the priority in $PATH. For instance, the system I am using has a couple version of sort:

$ which sort
~/coreutils-8.25/bin/sort
$ ~/coreutils-8.25/bin/sort --version | head -n 1
sort (GNU coreutils) 8.25
$ /bin/sort --version | head -n 1
sort (GNU coreutils) 8.4

On the system I am using, the version from GNU coreutils 8.25 is selected by an invocation of sort because of its precedence in PATH. However, the MANPATH environment variable on the system has been established such that the man page for the sort from GNU coreutils 8.4 is displayed (i.e., for /bin/sort, which is not the binary having precedence).

A three-part question arises from this scenario.

First, is there a simple way to instruct man (or the shell) to use or produce a form of MANPATH that reflects PATH, or must one do this manually (i.e., by finding the paths to the man pages that are associated with each entry in PATH and then concatenating these man paths in the same order as PATH, an exercise that would have to be repeated any time a change is made to PATH)? Were there a mechanism to establish concordance between PATH and MANPATH, then the expected man page would be displayed automatically, avoiding the problem of inadvertently reading a man page for a version other than the one used by default.

Second, is there a command that allows one to quickly determine the path of the default man page (e.g., something akin to which "man sort", which would report the path of the man page that is displayed when executing man sort). For instance, when I type man sort, I have no indication of the specific file on the system that is being delivered to the pager.

Third, is there a way to obtain the man page for an explicit version of a command (something like man ~/coreutils-8.25/bin/sort in my case for the GNU coreutils 8.25 version of sort, rather than having to track down the associated file, which in my case can be found to be ~/coreutils-8.25/share/man/man1/sort.1 or ~/coreutils-8.25/man/sort.1).

user001
  • 3,698
  • You appear to have a local installation of coreutils. Why? It's generally a bad idea to have local installs unless really necessary, and in this case, I don't see the necessity. – Faheem Mitha May 06 '16 at 23:35
  • @FaheemMitha : I am using a cluster and don't want to use the provided version of coreutils, which I am unable to change. So I have put another version in my home directory for personal use. – user001 May 06 '16 at 23:37
  • If @FaheemMitha hadn't commented that, I would have suggested that you report it to your distribution's support as it simply reflects a bad installation. You should find a way to address the problems properly. Having multiple versions of the same software is a good way of getting weird problems for nothing. – Julie Pelletier May 07 '16 at 00:05
  • what's so bad about coreutils 8.4 that you have to have a local install of version 8.25? wouldn't it be better to just write your scripts etc so that they used the system version of coreutils? – cas May 07 '16 at 01:38
  • @cas : I want the --parallel option for sort – user001 May 07 '16 at 02:14
  • @JuliePelletier : I agree. Unfortunately the cluster is used by thousands of individuals and I wouldn't be able to effect a change of core system binaries, hence my installation of a parallel set of utilities. – user001 May 07 '16 at 02:18

4 Answers4

1

For local installs such as that, I use a shell-script to setup the PATH, LD_LIBRARY_PATH and MANPATH values so that I get consistent results. Without a prop like that, you will not get automatic consistent results.

Here is an old example:

#!/bin/bash
# $Id: with-ncurses,v 1.1 2006/09/02 23:04:39 tom Exp $
export LIBS="-lncursesw"
for prefix in \
        /usr/local/ncurses6
do
        test  -f $prefix/lib/libncursesw.so && break
        test  -f $prefix/lib/libncursesw.a  && break
done

if [ -d $prefix/include/ncursesw ] ; then
        export CPPFLAGS="-I$prefix/include/ncursesw $CPPFLAGS"
        if [ $prefix != /usr ] ; then
                export CPPFLAGS="-I$prefix/include $CPPFLAGS"
        fi
fi

if [ $prefix != /usr ] ; then
        export PATH=`newpath -bd $prefix/bin`
        export LD_LIBRARY_PATH=`newpath -n LD_LIBRARY_PATH -bd $prefix/lib`
        export LIBS="-L$prefix/lib $LIBS"
        # this doesn't work for db30:
        # export LIBS="-static -L$prefix/lib $LIBS -shared"
fi

case `partition` in
rh*|md*)
        export MANPATH=$prefix/man:`manpath`
        ;;
*)
        export MANPATH=$prefix/man:`manpath -q`
        ;;
esac
eval $*

Making scripts like that portable is a problem, since there are no standards for the way MANPATH is used. But you can adapt things like that for specific systems.

The script, by the way, uses newpath to modify those variables and avoid duplicates.

Thomas Dickey
  • 76,765
  • Thanks for mentioning LD_LIBRARY_PATH and providing your script, which I will try to adapt to my system. – user001 May 06 '16 at 23:46
1

2. You almost have it.  man -w sort shows you where it gets the man page for sort.

1 & 3. Probably not, since man pages can be anywhere.
3. You can do a brute-force search:

find / -name "sort.1*"
  • Thanks, I didn't know about man -w. That's exactly what I wanted for #2. I was worried that what you said about 1 & 3 would be true. I also used find to find the man pages for the relevant version of sort. – user001 May 07 '16 at 02:18
1

Add the following to your ~/.bashrc or ~/.profile:

export MANPATH="$HOME/coreutils-8.25/share/man:$(manpath)"

This will put your man page tree in $MANPATH first, before the default MANPATH (as supplied by the manpath command)

cas
  • 78,579
1

Assuming that you put your man pages next to your executables (i.e. executables in /somewhere/bin, man pages in /somewhere/man/manSECTION), and you're using a man implementation with a manpath command, such as most Linux systems and FreeBSD and OS X, just run manpath. It constructs a MANPATH variable that's parallel to your `PATH.

unset MANPATH
MANPATH=$(manpath)