bash - Bash 脚本获取自身完整路径的可靠方法

标签 bash path

<分区>

我有一个 Bash 脚本需要知道它的完整路径。我试图找到一种广泛兼容的方式来做到这一点,而不会以相对或看起来很时髦的路径结束。我只需要支持 Bash,不需要支持 sh、csh 等。

到目前为止我发现了什么:

  1. Getting the source directory of a Bash script from within 的公认答案 地址通过 dirname $0 获取脚本的路径,这很好,但可能会返回一个相对路径(如 . ),如果你想改变脚本中的目录并且路径仍然指向脚本的目录,这就是一个问题。尽管如此,dirname 仍将是拼图的一部分。

  2. Bash script absolute path with OS X 的公认答案 (特定于 OS X,但无论如何答案都有效) 提供了一个函数,该函数将测试 $0 是否看起来是相对的,如果是这样,将预先考虑 $PWD 到它。但是结果中仍然可以有相对位(尽管总体上它是绝对的)——例如,如果脚本是目录 /usr/bin 中的 t 并且您是在 /usr 中输入 bin/../bin/t 来运行它(是的,这很复杂),你最终会得到 /usr/bin/../bin 作为脚本的目录路径。哪个有效,但是...

  3. readlink 解决方案 on this page ,看起来像这样:

    # Absolute path to this script. /home/user/bin/foo.sh
    SCRIPT=$(readlink -f $0)
    # Absolute path this script is in. /home/user/bin
    SCRIPTPATH=`dirname $SCRIPT`
    

    但是 readlink 不是 POSIX,显然解决方案依赖于 GNU 的 readlink,其中 BSD 出于某种原因无法工作(我无法访问 BSD - 类似系统进行检查)。

因此,有多种实现方法,但它们都有各自的注意事项。

什么是更好的方法? “更好”的意思是:

  • 给我绝对路径。
  • 即使以令人费解的方式调用时也能去除时髦的部分(参见上面#2 的评论)。 (例如,至少适度规范化路径。)
  • 仅依赖于 Bash 主义或几乎肯定会在最流行的 *nix 系统(GNU/Linux、BSD 和类似 BSD 的系统,如 OS X 等)上使用的东西。
  • 尽可能避免调用外部程序(例如,更喜欢 Bash 内置程序)。
  • (已更新,感谢您的提醒,wich)它不必解析符号链接(symbolic link)(事实上,我更希望它让它们单独存在,但这不是要求)。

最佳答案

这是我想出的(编辑:加上 sfstewmanlevigrokerKyle StrandRob Kennedy 提供的一些调整),这似乎最符合我的“更好”标准:

SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"

SCRIPTPATH 行似乎特别迂回,但我们需要它而不是 SCRIPTPATH=`pwd` 以便正确处理空格和符号链接(symbolic link)。

包含输出重定向 (>/dev/null 2>&1) 处理罕见的 (?) 情况,其中 cd 可能产生会干扰周围环境的输出$( ... ) 捕获。 (比如cd being overridden to also ls a directory 切换到它之后。)

另请注意,深奥的情况,例如执行根本不是来自可访问文件系统中的文件的脚本(这是完全可能的),不适合那里(或在我的任何其他答案中见过)。

cd 之后和 "$0" 之前的 -- 是为了防止目录以 - 开头.

关于bash - Bash 脚本获取自身完整路径的可靠方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32913211/

相关文章:

bash - 用 cygwin 打开 chrome

Prolog中的寻路

rust - 如何更改 Rust 中 &Path 的第一个祖先?

linux - 如何在bash脚本中串行运行sql脚本?

python - 递归树中的每条路径

java - ZipEntry 的路径名称的文件分隔符?

Python:获取给定文件夹中特定文件类型的名称

bash - 遍历跳过第一个参数

Bash 整数比较

linux - CMake 获取 HOSTNAME 环境变量