这个问题与:Getting the source directory of a Bash script from inside - 在那个问题中,有一个完美的答案显示 show 以获取当前运行的 bash 脚本的目录(包括读取符号链接的实际位置)。
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null && 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" )" >/dev/null && pwd )"
这完美地工作,除了它是很多样板代码。我正在开发一个脚本包,其中包含许多相互使用的小脚本。此脚本包托管在 git repo 中,它必须与位置无关。例如,无论它被克隆到哪个目录,它都应该始终以相同的方式工作。必须能够将此 repo 克隆到许多不同的目录中并独立使用它们。许多脚本只是命令的包装器,或者它们正在调用同一目录中的其他脚本,或者相对于包含目录。例如,这是一个模拟 'mongo' 命令的命令,但在 docker 容器中运行它:
#!/bin/bash
set -e
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null && 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" )" >/dev/null && pwd )"
# mongo-container is another script that determines the container id
# and it must be referenced relatively to the containing directory
MONGOE="docker exec -ti `${DIR}/mongo-container`"
${MONGOE} mongo "$@"
这段代码的 90% 用于确定脚本的目录,只有 10% 做了一些有用的事情。我有大约 20 个这样的脚本。这意味着我 90% 的 bash 脚本只是“确定包含目录”。当我看着它们时,我几乎看不到它们在做什么,因为有太多的样板代码。一定有更好的方法,我就是想不通。
有任何想法吗?