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

查看:72
本文介绍了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是否看起来是相对的,如果是这样,则将其挂起$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).

推荐答案

这就是我想出的(加上 levigroker Rob 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).

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

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