0

A common packaging issue I encounter is when a tool is looking for relative resources in its root directory (install directory).

Eg. pkg-name (/usr/share/pkg-name/pkg-name) is looking for resourceA (/usr/share/pkg-name/resourceA) so you can't call /usr/share/pkg-name/pkg-name directly unless your $PWD = /usr/share/pkg-name/, because if you're elsewhere (eg. /home/user) that tool will look for /home/user/resourceA and raise an error. So your are forced to create a wrapper like the following one: /usr/bin/pkg-wrapper

#!/bin/sh
cd /usr/share/pkg-name
exec pkg-name "\$@"

Now you can call /usr/bin/pkg-wrapper from whatever you want but a new issue is facing you! By adding cd /usr/share/pkg-name in your wrapper, $PWD = /usr/share/pkg-name in the context of the script. So imagine that pkg-wrapper -o file can write a file, now pkg-wrapper -o file will try to save the file file at /usr/share/pkg-name/file (current/working directory in the script context) and not at /home/user/file (current/working directory from where you are calling the wrapper). So files are now saved not in the folder you would like and if /usr/share/pkg-name/ is write protected you will get a permission error anyway. So you can't use relative file path anymore and are forced to either specify absolute path eg. pkg-wrapper -o /home/user/file or a little trick like pkg-wrapper -o "$(pwd)/file" or pkg-wrapper -o "$PWD/file".

Is there an agnostic way to solve this common issue? If not a way to patch ruby & python to use the "user current directory" rather than the script/process current directory? I already looked bash set options, bundle exec options.

For example a wrapper for a ruby script could be like the following if the --magicoption option existed to specify the the root directory where to look Gemfile, vendor/ and .bundle/ from.

#!/bin/sh
exec bundle exec /usr/share/pkg-name/pkg-name.rb --magicoption /usr/share/pkg-name/ "\$@"

This is just an example for a ruby package but it's the same issue for any script / binary from any language.

0

There is no solution that works for any type of script, that would be like having two working directories.

Your best bet is, in your wrapper

  • resolve the arguments referring to files with the real path,
  • then change to the directory of the script
  • and run the program with the replaced/full paths to the arguments

For example:

#!/bin/bash
# parse args that reference files
ARG=$(realpath $1)
cd /usr/share/pkg-name
exec bundle exec pkg-name.rb "$ARG"
2
  • That's a nice idea but that works only is there is one positional argument expecting a path, else with tons of classic args that would requires to do the arg parsing in the wrapper. So maybe the only real solution is about fixing tools upstream to have the path handled correctly so they can be called from outside its install directory. But I lack of example to show to upstream authors/maintainers. – noraj Sep 26 '20 at 11:20
  • I think you need to ask a more specific question if you want an example - e.g. limit yourself to ruby. But then the question is better suited for stackoverflow. – laktak Sep 28 '20 at 18:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.