Shell tips: Can a Bash script tell what directory it's stored in?
Question:
How do I get the path of the directory in which a Bash script is located FROM that Bash script?
Answer:
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
is a useful one-liner which will give you the full directory name of the script no matter where it is being called from.
This will work as long as the last component of the path used to find the script is not a symlink (directory links are OK). If you want to also resolve any links to the script itself, you need a multi-line solution:
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
This last one will work with any combination of aliases,
source
, bash -c
, symlinks, etc.
Beware: if you
cd
to a different directory before running this snippet, the result may be incorrect! Also, watch out for $CDPATH
gotchas.
To understand how it works, try running this more verbose form:
#!/bin/bash
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
TARGET="$(readlink "$SOURCE")"
if [[ $TARGET == /* ]]; then
echo "SOURCE '$SOURCE' is an absolute symlink to '$TARGET'"
SOURCE="$TARGET"
else
DIR="$( dirname "$SOURCE" )"
echo "SOURCE '$SOURCE' is a relative symlink to '$TARGET' (relative to '$DIR')"
SOURCE="$DIR/$TARGET" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
fi
done
echo "SOURCE is '$SOURCE'"
RDIR="$( dirname "$SOURCE" )"
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
if [ "$DIR" != "$RDIR" ]; then
echo "DIR '$RDIR' resolves to '$DIR'"
fi
echo "DIR is '$DIR'"
And it will print something like:
SOURCE './scriptdir.sh' is a relative symlink to 'sym2/scriptdir.sh' (relative to '.')
SOURCE is './sym2/scriptdir.sh'
DIR './sym2' resolves to '/home/ubuntu/dotfiles/fo fo/real/real1/real2'
DIR is '/home/ubuntu/dotfiles/fo fo/real/real1/real2'
Instance:
For SICER, if you are going to the original code, you have to copy the source code to your working directory.
This is because the PATHTO variable varies when you’re doing different work.
To avoid this, you can modify the code to:
PATHTO="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"#SICER=$PATHTO/SICERSICER=$PATHTOPYTHONPATH=$SICER/libexport PYTHONPATH
References:
http://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in
Comments
Post a Comment