如何获取其中的目录路径的Bash脚本位于,里面那个脚本?
我想使用 Bash 脚本作为另一个应用程序的启动器。我想将工作目录更改为 Bash 脚本所在的目录,以便我可以对该目录中的文件进行操作,如下所示:
$ ./application
#!/usr/bin/env bash SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
是一个有用的单行程序,无论从何处调用脚本,它都会为您提供脚本的完整目录名称。
只要用于查找脚本的路径的最后一个组件不是符号链接(目录链接正常),它就会起作用。如果您还想解析脚本本身的任何链接,则需要多行解决方案:
#!/usr/bin/env 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 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 located done DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )
最后一个将适用于别名、source、bash -c、 符号链接等的任意组合。
source
bash -c
注意:如果您cd在运行此代码段之前到不同的目录,结果可能不正确!
cd
此外,如果用户巧妙地覆盖 cd 以将输出重定向到 stderr(包括转义序列,例如在 Mac 上调用时),请注意$CDPATHgotchas和 stderr 输出副作用update_terminal_cwd >&2。>/dev/null 2>&1在cd命令末尾添加将处理这两种可能性。
$CDPATH
update_terminal_cwd >&2
>/dev/null 2>&1
要了解它是如何工作的,请尝试运行这个更详细的表单:
#!/usr/bin/env 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" )" >/dev/null 2>&1 && pwd ) if [ "$DIR" != "$RDIR" ]; then echo "DIR '$RDIR' resolves to '$DIR'" fi echo "DIR is '$DIR'"
它会打印如下内容:
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'
使用dirname "$0":
dirname "$0"
#!/bin/bash echo "The script you are running has basename `basename "$0"`, dirname `dirname "$0"`" echo "The present working directory is `pwd`"
pwd如果您不是从脚本所在的目录运行脚本,单独使用将不起作用。
pwd
[matt@server1 ~]$ pwd /home/matt [matt@server1 ~]$ ./test2.sh The script you are running has basename test2.sh, dirname . The present working directory is /home/matt [matt@server1 ~]$ cd /tmp [matt@server1 tmp]$ ~/test2.sh The script you are running has basename test2.sh, dirname /home/matt The present working directory is /tmp