当前位置:  开发笔记 > 编程语言 > 正文

从脚本本身获取Bash脚本的源目录

如何解决《从脚本本身获取Bash脚本的源目录》经验,为你挑选了33个好方法。

如何获取其中的目录路径的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>&1cd命令结束时添加将兼顾两种可能性.

要了解它的工作原理,请尝试运行此更详细的表单:

#!/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

殉情放开那只小兔子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有