0

The following code from https://stackoverflow.com/a/920834/156458is to get the pathname to the parent directory of a script inside the script, even if the script is run via a symlink to it:

if [ -L $0 ] ; then
    DIR=$(dirname $(readlink -f $0)) ;
else
    DIR=$(dirname $0) ;
fi ;

Is the above code equivalent to

DIR=$(dirname $(readlink -f $0)) ;

i.e. is there really a need to test if $0 is a symlink, and run different commands if yes and if no?

Why not just use $(dirname $(readlink -f $0)) regardless of whether $0 contains symlink or not?

Specifically, if $0 contains symlink, then it is perfect to use $(dirname $(readlink -f $0)).

if $0 is not a symlink, then it seems perfect to me to just use $(dirname $(readlink -f $0)):

  • $(readlink -f $0) returns the absolute path of $0, and $(dirname $(readlink -f $0)) returns the absolute path to the parent directory of $0

  • $(dirname $0) returns a path to the parent of $0, whether the return is an absolute or relative path depending on if $0 is an absolute or relative path.

  • I don't think whether the value of DIR is an absolute or relative path is important in the original code, because in either case, the value of DIR refers to the parent directory of $0. So are $(dirname $(readlink -f $0)) and $(dirname $0)equivalent in the original code?

Thanks.

1

You should use "$0" and dirname "$()".

The commands are not equivalent because the shell test affects only the last component in the path but readlink -f affects all path levels.

mkdir physdir
touch physdir/file
ln -s physdir symlink
test -L symlink/file ; echo $?
    1
test -L symlink ; echo $?
    0
dirname symlink/file
    symlink
dirname "$(readlink -f symlink/file)"
    /crypto/home/hl/tmp/stackexchange/readlink/physdir

So for relative paths the output is quite different but even for absolute paths the symlink directories within differ.

  • Thanks. Still not sure about my question "If $0 is not a symlink, then are $(dirname $(readlink -f $0)) and $(dirname $0) equivalent?" see my edit – Tim Mar 21 '18 at 15:42
  • What do you mean by "the shell test affects only the last component in the path" and "readlink -f affects all path levels"? – Tim Mar 21 '18 at 16:06
  • @Tim See my edit. – Hauke Laging Mar 22 '18 at 10:58
  • Thanks. I see. I just clarified my question, see my edit. – Tim Mar 23 '18 at 20:10
  • My question is actually: Why not just use $(dirname $(readlink -f $0)) regardless of whether $0 contains symlink or not? – Tim Mar 24 '18 at 15:53
1

I think whether there's a difference or not depends on the exact flavor of unix that you're using. On OSX for example, readlink doesn't have a -f flag and states:

If the given argument is not a symbolic link, readlink will print nothing and exit with an error

If you know that your OS supports the -f flag then there shouldn't be any difference.

In fact the -m flag might be the most flexible one to use.

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.