如何获取其中的目录路径的Bash脚本位于,里面那个脚本?
例如,假设我想使用Bash脚本作为另一个应用程序的启动器.我想将工作目录更改为Bash脚本所在的目录,因此我可以对该目录中的文件进行操作,如下所示:
$ ./application
dogbane.. 6204
#!/bin/bash DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
是一个有用的单行程序,它将为您提供脚本的完整目录名称,无论它在何处被调用.
只要用于查找脚本的路径的最后一个组件不是符号链接(目录链接正常),它就会起作用.如果您还想解决脚本本身的任何链接,则需要一个多行解决方案:
#!/bin/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
,符号链接等.
注意:如果您cd
在运行此代码段之前访问其他目录,结果可能不正确!
另外,如果用户巧妙地重写了cd以将输出重定向到stderr(包括转义序列,例如在Mac上调用时),请注意$CDPATH
陷阱和stderr输出副作用update_terminal_cwd >&2
.>/dev/null 2>&1
在cd
命令结束时添加将兼顾两种可能性.
要了解它的工作原理,请尝试运行此更详细的表单:
#!/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" )" >/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 $(readlink -f $ 0)````是正确的命令.有关测试用例,请参阅https://gist.github.com/tvlooy/cbfbdb111a4ebad8b93e (158认同)
@tvlooy IMO你的答案也不是很好,因为当路径中有空格时它会失败.与换行符相比,这不太可能,甚至不常见.`dirname"$(readlink -f"$ 0")"`不会增加复杂性,并且对于最小的麻烦来说,公平的措施更加健壮. (139认同)
您可以将此方法与user25866的答案融合,以获得与`source