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, sourcebash -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/SICER
SICER=$PATHTO
PYTHONPATH=$SICER/lib
export PYTHONPATH

References:
http://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in

Comments

Popular posts from this blog

gspread error:gspread.exceptions.SpreadsheetNotFound

Miniconda installation problem: concurrent.futures.process.BrokenProcessPool: A process in the process pool was terminated abruptly while the future was running or pending.

转载:彻底搞清楚promoter, exon, intron, and UTR