#!/usr/bin/env bashSOURCE=${BASH_SOURCE[0]}while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && 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 locateddoneDIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )6 Z2 G f3 ?1 x* H" T
最后一个将适用于别名,source、bash -c、 任何组合,如符号链接。 : r# f% B* r+ k7 P& U注意:如果您cd在运行此代码段之前,结果可能不正确!' c: b$ g/ A, j2 p" j7 t
另外,如果用户巧妙地覆盖 cd将输出重定向 stderr(包括转义序列,如 Mac 上调时请注意)$CDPATHgotchas和 stderr 输出副作用update_terminal_cwd >&2。>/dev/null 2>&1在cd在命令结束时添加这两种可能性。& I! j( C/ I% P' a( M( I
要了解它是如何工作的,请尝试操作更详细的表格: r7 O5 h" M% B% c* B
#!/usr/bin/env bashSOURCE=${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 fidoneecho "SOURCE is '$SOURCE'"RDIR=$( dirname "$SOURCE" )DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )if [ "$DIR" != "$RDIR" ]; then echo "DIR '$RDIR' resolves to '$DIR'"fiecho "DIR is '$DIR'"4 O/ {! ?1 o; }# _ K
它将打印以下内容: ) N9 i3 i7 [8 a1 x% s; ^' f2 j
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' : R t5 A: R* f9 e% C