The variable $0 points to the shell script that you execute itself. So if you have a file in that contains this
#!/bin/sh
echo "$0"
and copy it to /bin/my-script and to ~/somewhere/my-script-2, make both copies executable you can observe this behavior (I assume /bin is in your $PATH):
$ my-script
/bin/my-script
$ ~/somewhere/my-script-2
/home/luc/somewhere/my-script-2
$ cd
$ somewhere/my-script-2
somewhere/my-script-2
$ ../../bin/my-script
../../bin/my-script
$ cd /bin
$ ./my-script
./my-script
and so on.
In an interactive shell $0 points to the shell you execute and that is most probably in /bin. So if you source the above shell scripts you will always see the path to your shell interpreter: /bin/bash . For this the two script don't have to be executable:
$ . my-script
/bin/bash
$ . ~/somewhere/my-script-2
/bin/bash
$ cd
$ . somewhere/my-script-2
/bin/bash
$ . ../../bin/my-script
/bin/bash
$ cd /bin
$ . ./my-script
/bin/bash
The reason is that a sourced script is executed in the same process that sources it and $0 is not changed ($@ is updated though).
If dirname "$0" prints /bin for you, that just means the file you execute is in /bin or you are running dirname from a interactive session or a sourced script and the interpreter you use is in /bin.
Some other points:
- You don't need to do
echo "$(dirname "$0")", dirname "$0" will do the same.
- Use
pwd the get the current working directory.
- Put quotes around
$0 and command substitution as you might run into problems otherwise. Try something like cd $(echo a b c) to see the problem.
. /path/to/script.sh$0is probably/bin/bash(i.e. your current command-line shell) from the sourced script's POV.