6

There is my simple script that I try

#!/bin/bash DIR="$(cd "$(dirname $0)" && pwd)" echo $DIR

When I execute it like $ ./my_script.sh, get the path correctly.
But, when I source it like $ source my_script.sh, it gets the path /bin

How can I get the path of script by source it?
What is the different between source and execute?

NEET
  • 63

1 Answers1

9

The difference between sourcing a a script and "running it" is that when you source it (using source or .), the script is executed in the current shell environment, while if you "run it", a new shell process is started. You want to source scripts that you want would change the current shell environment. A script that is run in a separate shell process can not change the parent shell's environment. By "environment" is meant, for example, values of shell and environment variables, the current working directory etc.

A script is usually written to either be sourced or to be executed in its own shell environment, but very seldom both. A script that is made to be sourced is sometimes called a "dot-script" (since . is the standard command for sourcing such a script; source is a bash "alias" for .).

A dot-script being sourced by a bash shell can find its location by examining the first element of the BASH_SOURCE array:

printf 'My location: %s\n' "$( dirname "${BASH_SOURCE[0]}" )"

The directory path will be relative to the current working directory at the time of invoking source or . on the script.

Kusalananda
  • 333,661
  • Anyone know how to do this on FreeBSD? ${BASH_SOURCE[0]} doesn't work. – MiloDC Feb 12 '22 at 21:35
  • 1
    @MiloDC If you use the bash shell, then this should work. If it doesn't, then you are either not using the bash shell, or you are trying to do something different from what the user in the question is doing (figuring out the script's location from within a dot-script). You may want to look at the question that this question is a duplicate of. – Kusalananda Feb 13 '22 at 10:51