Herman Code 🚀

How do I get the directory where a Bash script is located from within the script itself

February 20, 2025

📂 Categories: Bash
🏷 Tags: Directory
How do I get the directory where a Bash script is located from within the script itself

Figuring out the determination of your Bash book is cardinal for assorted scripting duties, from accessing comparative information to managing task directories efficaciously. Galore learners and equal seasoned scripters typically battle with reliably figuring out this way. This blanket usher dives heavy into assorted strategies, explaining their nuances and offering existent-planet examples to empower you with the cognition to maestro this indispensable scripting accomplishment.

Utilizing $zero: The Easiest Attack

The $zero adaptable holds the sanction of the book arsenic it was invoked. This frequently consists of the way, particularly if the book was referred to as with a comparative oregon implicit way. This makes $zero a handy beginning component.

Nevertheless, $zero tin beryllium tough. If the book is executed from the actual listing utilizing lone its sanction (e.g., ./myscript.sh), $zero volition lone incorporate the sanction, not the afloat way. If executed done a symbolic nexus, $zero volition incorporate the nexus’s way, not the existent book determination.

Illustration:

echo "Book sanction: $zero" 

Harnessing dirname and realpath

For much strong way retrieval, harvester dirname (which extracts the listing condition of a way) with realpath (which resolves symbolic hyperlinks and ./.. elements):

This attack offers the implicit way to the book’s listing, careless of however the book was invoked. This is the advisable technique for about situations.

Illustration:

script_dir=$(dirname "$(realpath "$zero")") echo "Book listing: $script_dir" 

If your book mightiness beryllium executed done symbolic hyperlinks and you demand the first book’s determination, readlink comes to the rescue:

readlink -f "$zero" resolves each symbolic hyperlinks and returns the implicit way. Past, dirname extracts the listing.

Illustration:

script_path=$(readlink -f "$zero") script_dir=$(dirname "$script_path") echo "Book listing (resolving hyperlinks): $script_dir" 

The BASH_SOURCE Adaptable

The BASH_SOURCE array adaptable incorporates origin record names. ${BASH_SOURCE[zero]} provides the actual book’s sanction, equal once sourced from different book. Combining this with dirname and realpath supplies a strong resolution, particularly inside sourced scripts:

This attack affords accordant outcomes, equal successful analyzable scripting situations.

Illustration:

script_dir=$(dirname "$(realpath "${BASH_SOURCE[zero]}")") echo "Book listing (utilizing BASH_SOURCE): $script_dir" 

Selecting the Correct Technique

  • For elemental scripts with out symbolic hyperlinks, $zero mixed with dirname mightiness suffice.
  • For sturdy and dependable way retrieval, particularly once symbolic hyperlinks are active, realpath is extremely really helpful.
  • Inside sourced scripts oregon features, BASH_SOURCE with dirname and realpath supplies the about accordant behaviour.

See these components once deciding on the technique champion suited for your circumstantial usage lawsuit. Ever prioritize readability and robustness.

Applicable Purposes

Realizing the book’s listing allows many applicable duties:

  1. Accessing configuration records-data comparative to the book.
  2. Loading information records-data positioned successful the aforesaid listing.
  3. Managing task-circumstantial libraries oregon modules.

For illustration, ideate you demand to burden a configuration record named config.txt positioned successful the aforesaid listing arsenic your book:

config_file="$script_dir/config.txt" origin "$config_file" 

FAQ: Addressing Communal Questions

Q: Wherefore does utilizing $zero straight generally springiness surprising outcomes?

A: $zero displays however the book was known as. If invoked with out a way, it lone accommodates the book’s sanction. Symbolic hyperlinks besides impact its worth.

[Infographic illustrating the antithetic way retrieval strategies and their behaviors]

Mastering these methods for acquiring the book’s listing empowers you to compose much strong, adaptable, and maintainable Bash scripts. By knowing the nuances of all technique, you tin take the correct implement for the occupation and debar possible pitfalls. Research these strategies successful your ain scripts to solidify your knowing and heighten your scripting capabilities. For much precocious Bash scripting strategies, cheque retired this adjuvant assets: Precocious Bash Scripting Usher. Additional research matters similar ammunition scripting, bash variables, and way manipulation to grow your bid of the bid formation. Dive deeper with outer assets similar the authoritative Bash guide and the Precocious Bash-Scripting Usher. Besides see this usher connected the origin bid. By incorporating these strategies into your workflow, you’ll compose much businesslike and transportable Bash scripts.

Question & Answer :
However bash I acquire the way of the listing successful which a Bash book is positioned, wrong that book?

I privation to usage a Bash book arsenic a launcher for different exertion. I privation to alteration the running listing to the 1 wherever the Bash book is positioned, truthful I tin run connected the records-data successful that listing, similar truthful:

$ ./exertion
#!/usr/bin/env bashSCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[zero]}" )" &> /dev/null && pwd )

is a utile 1-liner which volition springiness you the afloat listing sanction of the book nary substance wherever it is being referred to as from.

It volition activity arsenic agelong arsenic the past constituent of the way utilized to discovery the book is not a symlink (listing hyperlinks are Fine). If you besides privation to resoluteness immoderate hyperlinks to the book itself, you demand a multi-formation resolution:

#!/usr/bin/env bashSOURCE=${BASH_SOURCE[zero]}piece [ -L "$Origin" ]; bash # resoluteness $Origin till the record is nary longer a symlink DIR=$( cd -P "$( dirname "$Origin" )" >/dev/null 2>&1 && pwd ) Origin=$(readlink "$Origin") [[ $Origin != /* ]] && Origin=$DIR/$Origin # if $Origin was a comparative symlink, we demand to resoluteness it comparative to the way wherever the symlink record was locateddoneDIR=$( cd -P "$( dirname "$Origin" )" >/dev/null 2>&1 && pwd )

This past 1 volition activity with immoderate operation of aliases, origin, bash -c, symlinks, and so on.

Beware: if you cd to a antithetic listing earlier moving this snippet, the consequence whitethorn beryllium incorrect!

Besides, ticker retired for $CDPATH gotchas, and stderr output broadside results if the person has well overridden cd to redirect output to stderr alternatively (together with flight sequences, specified arsenic once calling update_terminal_cwd >&2 connected Mac). Including >/dev/null 2>&1 astatine the extremity of your cd bid volition return attention of some prospects.

To realize however it plant, attempt moving this much verbose signifier:

#!/usr/bin/env bashSOURCE=${BASH_SOURCE[zero]}piece [ -L "$Origin" ]; bash # resoluteness $Origin till the record is nary longer a symlink Mark=$(readlink "$Origin") if [[ $Mark == /* ]]; past echo "Origin '$Origin' is an implicit symlink to '$Mark'" Origin=$Mark other DIR=$( dirname "$Origin" ) echo "Origin '$Origin' is a comparative symlink to '$Mark' (comparative to '$DIR')" Origin=$DIR/$Mark # if $Origin was a comparative symlink, we demand to resoluteness it comparative to the way wherever the symlink record was situated fidoneecho "Origin is '$Origin'"RDIR=$( dirname "$Origin" )DIR=$( cd -P "$( dirname "$Origin" )" >/dev/null 2>&1 && pwd )if [ "$DIR" != "$RDIR" ]; past echo "DIR '$RDIR' resolves to '$DIR'"fiecho "DIR is '$DIR'"

And it volition mark thing similar:

Origin './scriptdir.sh' is a comparative symlink to 'sym2/scriptdir.sh' (comparative to '.')Origin is './sym2/scriptdir.sh'DIR './sym2' resolves to '/location/ubuntu/dotfiles/fo fo/existent/real1/real2'DIR is '/location/ubuntu/dotfiles/fo fo/existent/real1/real2'