3

I'm looking for a way to get the real absolute path to the current /bin/sh script. It should work for situations like this one:

/path/to/symlink/in/PATH/somescript

    -> ../../Package/current/bin/somescript.sh

...where ../../Package/current is itself a symlink pointing to v1.23.

Important assumptions: we assume that readlink is available, but does not necessarily have the -f option.

Since the code of interest is contained in the script's file, this code can safely assume that all the symbolic links are legit, and ultimately point to the right place (otherwise code would not have been found by the shell and executed in the first place). IOW, there's no need to worry about symlink cycles, broken symlinks, etc.

Below I give my best attempt, but it strikes me as a bit of overkill. Is there a simpler way?


Here's my version:

path_to_script () {
  TARGET="$1"
  BASENAME="$(basename "$TARGET")"

  (
    cd -P "$(dirname "$TARGET")"
    if [ -h "$BASENAME" ]
    then
        path_to_script "$(readlink "$BASENAME")"
    else
        echo "$PWD/$BASENAME"
    fi
  )

}

PATH_TO_SCRIPT="$(path_to_script "$0")"

Basically, it recursively follows symbolic links, using cd -P to resolve symlinks in paths.

  • 3
    Does your readlink have the -f option? – cjm Jun 14 '16 at 17:25
  • @cjm: thanks for pointing this out; I'd meant to mention it, but somehow forgot to in the end. I've fixed my post to rectify the omission. – kjo Jun 14 '16 at 21:29
  • 2
    Can you assume GNU make? It has an absolute path function. If you're targeting developer machines, it's highly likely to be available. If you're targeting embedded systems, forget about it. – Gilles Jun 14 '16 at 21:32
  • @Gilles: I'm targeting "end-user *nix-based systems". I.e., primarily Ubuntu and Darwin users. – kjo Jun 14 '16 at 23:45
  • Usually I say "you must install the realpath program if you don't already have one" – o11c Jun 15 '16 at 1:40
0

I think this is not only shorter but also easier to read; YMMV.

path_to_script () {
    if ! [ -L "$1" ]; then
        echo "$1"
    else
        path_to_script "$(readlink "$1")"
    fi
}

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.