user1543495 user1543495 - 1 month ago 4
Linux Question

Can't execute from /usr/local/bin/ symlink

I've recently had to compile a program (Riak) from source since they don't have a repo available for Ubuntu 16.04 yet.

I've compiled the program and copied it to /opt/riak where it works fine.

Since this program requires sudo privileges, I've decided to symlink /opt/riak/bin/riak to /usr/local/bin/riak instead of adding the variable to the path via a profile.d file (because in order to work with sudo I'd have to remove env_reset from /etc/sudoers which I rather not do).

The error I get is the following:
/usr/local/bin/riak: 8: .: Can't open /usr/local/bin/../lib/

Shouldn't the symlink execute the file from the original's working directory? Is there a way to make it work?


The error message is almost self explanatory. Apparently the riak executable is trying to find a file called using a path relative to its own, namely ../lib/ Originally, this would resolve to the following path: /opt/riak/bin/../lib/, which is the same as /opt/riak/lib/ But now is trying to find the file at /usr/local/bin/../lib/ which is the same as /usr/local/lib/ and obviously the file is not there.

You have the following options (in order of preference):

  1. Leave the program in /opt and invoke it from there
  2. Leave the program in /opt and create a small wrapper shell script in /usr/local/bin that calls the original executable (see at the end of this post).
  3. Recompile the program passing the right parameters to its configure script (e.g. --prefix=/usr/local) so that it works from /usr/local.

I would recommend against option 3; I prefer to let the /usr directory be managed by the distos package manager. If I have to compile something myself, I prefer to put it in a dedicated directory bellow /opt. This way, if I want to remove it later on, I can just delete that directory.

Example wrapper script for option 2:

exec /opt/riak/bin/riak "$@"