1

Given that realpath command does not exists on every unix platform, I would like to replace realpath with readlink command in order to make my shell script as cross-platform as possible.

The thing is that realpath has the --relative-to parameter which is necessary in my case:

$ realpath bdd/full --relative-to bdd
full

on the other hand, readlink seems to provide only the main functionality of realpath command:

$ readlink -f bdd/full
/home/user/bdd/full

After reading the man page, I couldn't find any parameter similar to --relative-to.

Have you any idea if readlink supports a --relative-to-like functionality and if it's not, is there any "clean" way to achive such thing using readlink or any other cross-platform command?

UPDATE:

In my case, --relative-to is necessary for logging purposes, in my shell script, the user passes two relative paths, the relative of the base folder and the relative path of the file on which the action will be performed. In order to print a more-human friendly log entry, I want to print the relative path of file from the base folder path.

I'm currently using the following function to achive my goal:

get_relative_path () {
  if command -v realpath &> /dev/null
  then
    realpath --relative-to="${2-$PWD}" "$1"
  else
    python -c 'import os.path, sys;print os.path.relpath(sys.argv[1],sys.argv[2])' "$1" "${2-$PWD}"
  fi
}
  • Could you give us some more details on why you need this? readlink doesn't have any equivalent to --relative-to, but if you explain why you need it, we might be able to come up with a workaround. – terdon Mar 15 '21 at 16:58
  • There seems not to be any easy alternative to realpath: see, for instance https://unix.stackexchange.com/q/85060/315749 or https://stackoverflow.com/q/2564634/10488700 on Stack Overflow – fra-san Mar 15 '21 at 17:42
  • Your example gives the same output as say basename PATH - are you just trying to get the last element? or do you intend something else? Unfortunately this is a difficult problem to solve for large numbers of platforms - for instance on OSX readlink doesn't have -f option – Mr R Mar 15 '21 at 20:25
  • @terdon check out the update for further details – Panagiotis Simakis Mar 16 '21 at 10:00
  • @MrR basename is not enough in my case, file might be inside multiple sub-folders. You are right, I didn't know how difficult is to implement a cross-platform shell script :P – Panagiotis Simakis Mar 16 '21 at 10:01
  • It's unusual to print relative filenames (given a specific file input) ... for instance try /bin/ls /bin/foo/nonexistant ls: /bin/foo/nonexistant: No such file or directory [they just give you back exactly what you entered]. Additionally what if you get given a path which is relative the current directory - e.g. ./mary/had/a/little/lamb/ or without the dotslash mary/had/a/little/lamb will this give sensible results to the user?? – Mr R Mar 16 '21 at 10:16
  • Relative paths are ambiguous: if a program tells you it is running in a/ and using ../c/ and ../c/d/f, how can you know whether they actually were /x/y/a/, /x/y/c/ and /x/y/c/f, respectively, or /w/z/a/, /w/z/c/ and /w/z/c/f? In other words, do you really need relative paths instead of absolute ones? – fra-san Mar 16 '21 at 11:49

0 Answers0