【问题标题】:How to handle relative paths in a bash setup script?如何处理 bash 设置脚本中的相对路径?
【发布时间】:2020-10-15 02:15:17
【问题描述】:

我经常遇到这样的情况,即我想为 git 存储库之类的东西提供某种“设置”或“安装”脚本,尽管它也可以用于其他情况。

明确一点:“设置脚本”是指放置一些文件、检查一些东西、创建某些依赖项等的脚本。

问题是,如果我想使用与脚本相关的资源,或者想创建以存储库中的文件为目标的链接,我需要能够引用相对于存储库根目录的资源或构建绝对路径。

目前我总是这样:

SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)
ROOT=$(realpath "$SCRIPT_DIR/..")

但这似乎真的很糟糕,因为它很难理解并且基本上在每个 repo 甚至文件中都被复制了。

有没有更好的方法来做到这一点?这样的脚本不需要吗?

【问题讨论】:

  • 这适用于通用脚本目录(我确实使用类似的东西),但在我的情况下,我说的是每个存储库一个脚本,应该可以放在任何地方。
  • @Philippe 问题是如何编写一个脚本来引用与脚本位于同一目录中的文件。这是一个常见的问题。假设脚本有一个相关的配置文件位于它旁边。它不能简单地打开./script.cfg——当前目录可能不是脚本和配置文件所在的位置,比如用户是否使用/path/to/script而不是cd /path/to; ./script这样的绝对路径运行脚本。

标签: bash shell


【解决方案1】:

有没有更好的方法来做到这一点?

没有。

这样的脚本是否不需要?

没有。这很正常。

还有其他方法可以解决这个问题吗?

我的手指习惯于输入"$(dirname "$(readlink -f "$0")")",但这并不好。

也不要使用大写变量。它们不仅大喊大叫,而且还用于环境变量,例如 PWD LINES COLUMNS DISPLAY UID IFS USER 等。在脚本中首选小写变量。 (我想说ROOT 是一个非常常见的变量名,因此是不好的变量名。)

【讨论】:

    【解决方案2】:

    在 git repo 中,您可以使用 git rev-parse --show-toplevel 找到工作树的根,然后从那里开始。

    一般中,这是一个有点困难的问题。调用脚本的方法太多,可以改变 $0 的实际含义,因此您不能真正依赖它。在我看来,你能做的最好的事情就是建立一个标准(例如,通过期望环境中的某些值或坚持脚本以./path/from/root/to/script 执行),如果不是,则尝试以良好的错误消息退出。

    【讨论】:

    • 可悲的是 git rev-parse --show-toplevel 只能在 repo 内部工作,但我会记住这一点,谢谢。
    • @AK_is_curious 那么,在 repo 中必须成为你标准的一部分。抱歉,我不知道更好的方法。当然,您可以使用git -C path/to/repo,但没有什么可以替代知道您在哪里。
    • 我刚刚构建了这个:git -C "$(dirname "$0")" rev-parse --show-toplevel,它似乎工作得很好——至少在与 git 存储库相关的情况下使用它时。
    【解决方案3】:

    这可以提高脚本管理和可读性吗?

    #!/usr/bin/env bash
    
    source $HOME/common-tools/include.sh "${BASH_SOURCE[0]}"
    
    echo $ROOT
    

    在 $HOME/common-tools/include.sh 中:

    SCRIPT_DIR=$(cd "$( dirname "$1" )" >/dev/null 2>&1 && pwd)
    ROOT=$(realpath "$SCRIPT_DIR/..")
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-09
      • 2016-07-08
      • 2012-09-23
      • 2018-02-25
      • 2018-06-18
      • 2012-10-04
      • 1970-01-01
      • 2012-07-07
      相关资源
      最近更新 更多