Bash 脚本获取自身完整路径的可靠方法 [英] Reliable way for a Bash script to get the full path to itself

查看:17
本文介绍了Bash 脚本获取自身完整路径的可靠方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a Bash script that needs to know its full path. I'm trying to find a broadly-compatible way of doing that without ending up with relative or funky-looking paths. I only need to support Bash, not sh, csh, etc.

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

What I've found so far:

  1. 从内部获取 Bash 脚本的源目录 解决了通过 dirname $0 获取脚本的路径,这很好,但可能会返回一个 relative 路径(如 .),如果您想更改脚本中的目录并让路径仍然指向脚本的目录,这是一个问题.尽管如此,dirname 将成为难题的一部分.

  1. The accepted answer to Getting the source directory of a Bash script from within addresses getting the path of the script via dirname $0, which is fine, but that may return a relative path (like .), which is a problem if you want to change directories in the script and have the path still point to the script's directory. Still, dirname will be part of the puzzle.

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

The accepted answer to Bash script absolute path with OS X (OS X specific, but the answer works regardless) gives a function that will test to see if $0 looks relative and if so will pre-pend $PWD to it. But the result can still have relative bits in it (although overall it's absolute) — for instance, if the script is t in the directory /usr/bin and you're in /usr and you type bin/../bin/t to run it (yes, that's convoluted), you end up with /usr/bin/../bin as the script's directory path. Which works, but...

readlink 解决方案 在此页面上,如下所示:

The readlink solution on this page, which looks like this:

# 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- 类似系统检查).

But readlink isn't POSIX and apparently the solution relies on GNU's readlink where BSD's won't work for some reason (I don't have access to a BSD-like system to check).

所以,这样做的方法多种多样,但它们都有自己的警告.

So, various ways of doing it, but they all have their caveats.

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

What would be a better way? Where "better" means:

  • 给我绝对路径.
  • 即使在以复杂的方式调用时也会取出时髦的位(请参阅上面对 #2 的评论).(例如,至少适度规范化路径.)
  • 仅依赖 Bash 主义或几乎肯定会依赖*nix 系统(GNU/Linux、BSD 和类似 BSD 的系统,如 OS X 等)的大多数流行风格的东西.
  • 尽可能避免调用外部程序(例如,更喜欢 Bash 内置程序).
  • (更新,感谢提醒,wich)它没有解决符号链接(事实上,我更喜欢不理会它们,但这不是必需的).
  • Gives me the absolute path.
  • Takes out funky bits even when invoked in a convoluted way (see comment on #2 above). (E.g., at least moderately canonicalizes the path.)
  • Relies only on Bash-isms or things that are almost certain to be on most popular flavors of *nix systems (GNU/Linux, BSD and BSD-like systems like OS X, etc.).
  • Avoids calling external programs if possible (e.g., prefers Bash built-ins).
  • (Updated, thanks for the heads up, wich) It doesn't have to resolve symlinks (in fact, I'd kind of prefer it left them alone, but that's not a requirement).

推荐答案

这是我想出的(加上一些由 sfstewmanlevigrokerKyle StrandRob Kennedy),这似乎最适合我的更好"标准:

Here's what I've come up with (edit: plus some tweaks provided by sfstewman, levigroker, Kyle Strand, and Rob Kennedy), that seems to mostly fit my "better" criteria:

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

SCRIPTPATH 行看起来特别迂回,但我们需要它而不是 SCRIPTPATH=`pwd` 以便正确处理空格和符号链接.

That SCRIPTPATH line seems particularly roundabout, but we need it rather than SCRIPTPATH=`pwd` in order to properly handle spaces and symlinks.

包含输出重定向 (>/dev/null 2>&1) 可处理罕见的 (?) 情况,其中 cd 可能会产生会干扰的输出与周围的 $( ... ) 捕获.(例如 cd 也被覆盖为 ls 目录 切换到它之后.)

The inclusion of output redirection (>/dev/null 2>&1) handles the rare(?) case where cd might produce output that would interfere with the surrounding $( ... ) capture. (Such as cd being overridden to also ls a directory after switching to it.)

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

Note also that esoteric situations, such as executing a script that isn't coming from a file in an accessible file system at all (which is perfectly possible), is not catered to there (or in any of the other answers I've seen).

cd 之后和 $0" 之前的 -- 是在目录以 - 开头的情况下代码>.

The -- after cd and before "$0" are in case the directory starts with a -.

这篇关于Bash 脚本获取自身完整路径的可靠方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆