5

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
  • 53
  • 1
  • 5

1 Answers1

8

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
  • 320,670
  • 36
  • 633
  • 936
  • 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