bash脚本如何知道它来源时安装的目录。运营商?

时间:2009-01-07 19:41:47

标签: linux bash unix shell scripting

我想要做的是将文件中的设置包含到我当前的交互式bash shell中,如下所示:

$。 /path/to/some/dir/.settings

问题是.settings脚本还需要使用“。”运算符包含其他文件:

。 .extra_settings

如何在.settings文件中引用.extra_settings的相对路径?这两个文件始终存储在同一目录中,但此目录的路径将根据这些文件的安装位置而有所不同。

运营商始终知道/ path / to / some / dir /,如上所示。 .settings文件如何知道安装它的目录?我宁愿没有一个记录已安装目录名称的安装过程。

5 个答案:

答案 0 :(得分:18)

我相信$(dirname "$BASH_SOURCE")会做你想要的,只要您采购的文件符号链接。

如果您要采购的文件可能是符号链接,您可以执行以下操作以获取真实目录:

PRG="$BASH_SOURCE"
progname=`basename "$BASH_SOURCE"`

while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done

dir=$(dirname "$PRG")

答案 1 :(得分:7)

这可能是一个优雅的解决方案:

script_path="${BASH_SOURCE[0]}"
script_dir="$(cd "$(dirname "${script_path}")" && pwd)"

然而,在采购链接时,这不会起作用。在这种情况下,可能会做

script_path="$(readlink -f "$(readlink "${BASH_SOURCE[0]}")")"
script_dir="$(cd "$(dirname "${script_path}")" && pwd)"

注意事项:

  • ${array[x]}这样的数组不符合POSIX - 但是,BASH_SOURCE数组仅在Bash中可用,无论如何
  • 在macOS上,原生BSD readlink不支持-f,因此您可能需要使用例如readlink安装GNU brew install coreutilsreadlink brewgreadlink替换-e
  • 根据您的使用情况,您可能希望使用-m-f个开关,而不是-n加上{{1}};有关详细信息,请参阅readlink手册页

答案 2 :(得分:2)

对问题的不同看法 - 如果你正在使用“。”为了设置环境变量,另一种标准方法是让你的脚本回显变量设置命令,例如:

# settings.sh
echo export CLASSPATH=${CLASSPATH}:/foo/bar

然后评估输出:

eval $(/path/to/settings.sh)

这就像modules这样的包有效。这种方式也可以轻松支持从sh(X=...; export X)和csh(setenv X ...)派生的shell

答案 3 :(得分:0)

我尝试搞乱$(dirname $ 0)的变体但是当.settings文件包含在“。”中时它会失败。如果我正在执行.settings文件而不是包含它,那么这个解决方案就可以了。相反,$(dirname $ 0)总是返回“。”,表示当前目录。做这样的事情时失败了:

$ cd / $。 /some/path/.settings

答案 4 :(得分:0)

这种作品。它的工作原理是,您可以在.settings文件中使用$(dirname $ 0)语法来确定它的主页,因为您在新shell中执行此脚本。但是,它会添加额外的卷积层,您需要更改以下行:

export MYDATE=$(date)

echo "export MYDATE=\$(date)"

也许这是唯一的方法?