11

When I need to get path to the script file inside script itself I use something like this:

`dirname $0`

that works file until I call the script through sym link to it. In that case above code prints the location of the link instead the original file.

Is there a way to get the path of the original script file, not the link?

Thanks, Mike

Charles
  • 50,943
  • 13
  • 104
  • 142
Ma99uS
  • 10,605
  • 8
  • 32
  • 42
  • Ok. I have found the answer here: http://stackoverflow.com/questions/7665/how-to-resolve-symlinks-in-a-shell-script – Ma99uS May 28 '09 at 13:42

5 Answers5

17
if [ -L $0 ] ; then
    DIR=$(dirname $(readlink -f $0)) ;
else
    DIR=$(dirname $0) ;
fi ;
dsm
  • 10,263
  • 1
  • 38
  • 72
  • In case when readlink is not available the answer is here: http://stackoverflow.com/questions/7665/how-to-resolve-symlinks-in-a-shell-script – Ma99uS May 28 '09 at 13:43
  • Curious why do you need to run different commands when `$0` is a symlink or not? https://unix.stackexchange.com/questions/432475/apply-readlink-to-a-non-symlink-file – Tim Mar 21 '18 at 16:45
  • Why not just use `$(dirname $(readlink -f $0))`` regardless of whether $0` contains symlink or not? – Tim Mar 23 '18 at 20:11
17

You really need to read the following BashFAQ article:

The truth is, the $0 hacks are NOT reliable, and they will fail whenever applications are started with a zeroth argument that is not the application's path. For example, login(1) will put a - in front of your application name in $0, causing breakage, and whenever you invoke an application that's in PATH $0 won't contain the path to your application but just the filename, which means you can't extract any location information out of it. There are a LOT more ways in which this can fail.

Bottom line: Don't rely on the hack, the truth is you cannot figure out where your script is, so use a configuration option to set the directory of your config files or whatever you need the script's path for.

lhunath
  • 120,288
  • 16
  • 68
  • 77
6

Use readlink for that:

readlink -f "$0"
soulmerge
  • 73,842
  • 19
  • 118
  • 155
1
Dir=$(dirname $(readlink -f "$0"))
1

I suggest this one:

dirname $(realpath $0)

example:

skaerst@test01-centos7:~/Documents> ../test/path.sh 
dirname realpath: /home/skaerst/test

skaerst@test01-centos7:~/Documents> cat ../test/path.sh
#!/bin/bash

echo "dirname realpath: $(dirname $(realpath $0))"

works with symlinks too because realpath uses -P by default:

skaerst@test01-centos7:~/Documents> ln -s ../test/path.sh p
skaerst@test01-centos7:~/Documents> ./p
dirname realpath: /home/skaerst/test

realpath is available with coreutils >8.5, I guess

skaerst@test01-centos7:~/Documents> rpm -qf $(which realpath) $(which dirname)
coreutils-8.22-15.el7_2.1.x86_64
coreutils-8.22-15.el7_2.1.x86_64

hth

Regards

Stefan

StefanKaerst
  • 331
  • 2
  • 6