3

In this answer a method for adding all /opt/tool/bin subdirectories to PATH is presented:

for d in /opt/*/bin; do PATH="$PATH:$d"; done

But then the Gilles states:

But this is rarely done. The usual method when executables in non-standard directories are to be in $PATH is to make symbolic links in a directory in the path such as /usr/local/bin. The stow utility (or xstow) can be useful in that regard.

At least one other answer supports that assertion.

But I don't understand why symlinking to executables in /opt/*/bin is preferable. It seems this adds needless extra maintenance.

Why is a symlink the preferred solution for executables in opt, instead of updating PATH?

ilkkachu
  • 138,973
jac
  • 161
  • 5
    "the Gilles" :-) – Kusalananda Jul 01 '18 at 10:00
  • I would add /opt/bin and put that in my PATH. Then add symlinks to it. It reduces the search path of PATH. It also means that you don't have to update the PATH of all users, and when a new link is added, it will work immediately. – ctrl-alt-delor Jul 01 '18 at 10:57
  • @ctrl-alt-delor I set up PATH from /etc/environ and am using a home-developed /etc/profile, which includes also ~/bin to the PATH. I think, /usr/local/{s,}bin is a correct place for such symlinks. – peterh Jul 01 '18 at 21:38

3 Answers3

4

Trying to answer this without saying which solution is "best", but only to provide an explanation as to why Gilles might suggest using symbolic links for providing a set of tools, and addressing the maintainence aspect of that. In the end, it is the local administrator that decides what the appropriate solution on their system might be.

By adding the bin directories to users' PATH, adding a new tool would require an update to all user's PATH variable (which would not be in effect until a new shell session was started).

Using GNU stow, as Gilles suggest, you would have a directory structure under e.g. /opt/stow with one directory for each tool, each with its own bin, lib etc. subdirectory. Each tool would typically have been installed by specifying /opt/stow/toolname as the installation prefix.

The subdirectories would be symbolically linked to the corresponding directories under /opt by stow, so the maintenance cost is minimal. The only directories that you would have to add to PATH would be /opt/bin and possibly /opt/sbin.

Typically, you would have

/opt/stow/tool-A-1.23
/opt/stow/tool-A-1.25
/opt/stow/tool-B-3.0

Then:

cd /opt/stow
stow tool-A-1.23
stow tool-B-3.0

This would populate the /opt hierarchy with the appropriate symbolic links, allowing you to access the executables for both tools in /opt/bin. This is assuming there are no name clashes in the executables between the tools, but then again, you'd have the same issue when adding all those paths to PATH.

To switch from 1.23 to 1.25 of tool-A,

cd /opt/stow
stow -D tool-A-1.23
stow tool-A-1.25

There is never a need to manually maintain symbolic links or to change users' PATH, and the change would be immediate for all users.

Kusalananda
  • 333,661
  • ilkkachu's addition that adding all /opt/*/bin subdirectories can result in a cumbersomely long PATH variable is also a useful point -- the approach doesn't scale well. – jac Jul 01 '18 at 20:54
2

Putting all of /opt/*/bin in PATH has the downside that the list needs to be changed every time some new application is installed, or another updated (with a corresponding change in the path).

The users will need to log in again, or manually update their path. For simple login-do-stuff-logout use cases this might not be a problem, but for long-running sessions, like anyone running screen or tmux, it is. (You may have shells (or Emacs) running with the old PATH and the terminal multiplexer itself will have the old PATH, which matters if it ever runs utilities directly.)

In addition, the result of that will be a visually rather unpleasant list of directories, which you might not want to have the users need to see. It'll be easier for them to check what their PATH contains if they don't need to care about the details if stuff installed in /opt.

Also, if you ever need to explicitly set the PATH in something like crontab, it's easier to be able to just write /bin:/usr/bin/:/opt/bin or such, rather than have to write and update the list of actual directories in /opt. You can't use a loop and a glob in crontab.

As for the administrative overhead, Kusalananda discussed stow, but even without it, creating the necessary symlinks can be done by just running ln -s ../someutil-1.2.3/bin/* . within /opt/bin. (Removing old ones isn't that trivial, but then leaving broken links behind when you remove the directory for the utility doesn't affect the behaviour of the shell, it's just slightly unclean.)

ilkkachu
  • 138,973
0

The main problem that needs to be solved is program name clashes.

Having a large PATH it not a problem anymore since there is a hash for binary path locations in the Bourne Shell since e.g. 1977.

It is unusual to have symlinks except for one reason:

To be able to have an own selection of programs that differs from the cluster view.

If you e.g. set your PATH to:

PATH=/usr/gnu/bin:/usr/bin

you find all the GNU tools before the standard system tools.

This may allow you to use GNU tools easily, but this also results in being forced to e.g. use the GNU chmod that misses support for ACLs and to use GNU tar that is known for creating archives with portability issues.

Let us assume that you are basically interested in GNU xgettext but otherwise like to use the official system tools that include support for extended system features, the GNU tools are not aware of. This could be done by creating an own bin directory be e.g. calling:

mkdir ~/bin

If you then create a symlink:

cd ~/bin
ln -s /usr/gnu/bin/xgettext

and set up this PATH:

PATH=~/bin:/usr/bin:/usr/gnu/bin

you will get GNU xgettext if you call xgettext but the official system tools if you call e.g. chmod or tar. Since it is usual to have symlinks to the GNU tools but with their native prefix in /usr/bin/ (e.g. /usr/bin/gtar to /usr/gnu/bin/tar) you still may intentionally use GNU tar by calling gtar.

BTW: /opt/bin is not part of the UNIX FHS standard and this standard lists

/opt/<vendor>/bin

and not

/opt/<project>/bin

even though there are examples for the latter.

schily
  • 19,173