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
$0
is probably/bin/bash
(i.e. your current command-line shell) from the sourced script's POV.