通过符号链接执行时获取当前脚本的路径


58

我有一个实用程序,该实用程序由几个目录以及一些bash脚本和支持文件组成,这些文件可能会部署到多台计算机上,并且可能位于每台计算机的不同目录中。脚本需要能够引用相对于它们自己的路径,因此我需要能够获取到当前正在执行的文件的路径。

我知道dirname $0当直接调用我的脚本时,这种用法非常有效。不幸的是,人们希望能够从完全不同的目录创建指向这些脚本的符号链接,并且仍然具有相对的路径逻辑功能。

总体干线结构的示例如下:

/
 |-usr/local/lib
 |  |-foo
 |  |  |-bin
 |  |  |  |-script.sh
 |  |  |-res
 |  |  |  |-resource_file.txt
 |-home/mike/bin
 |  |-link_to_script (symlink to /usr/local/lib/foo/bin/script.sh)

我怎样才能可靠地引用/usr/local/lib/foo/res/resource_file.txt来自script.sh它是否被调用/usr/local/lib/foo/bin/script.sh~mike/bin/link_to_script

Answers:


79

尝试将其作为通用解决方案:

DIR="$(cd "$(dirname "$0")" && pwd)"

在以下符号链接的特定情况下,您也可以这样做:

DIR="$(dirname "$(readlink -f "$0")")"

完美运行,并且比我尝试过的东西更简单。谢谢!
Mike Deck

@MikeDeck享受。请注意,自首次发布以来,我已修复了一些引用问题……如果您的路径中有时有空格或其他古怪的字符,则可以使用最新编辑中的一个选项。即使对这个项目无关紧要,您也可以从自己的脚本中复制代码,然后选择最佳选项就可以了!
卡莱布

1
我应该澄清一下,第二个完美地工作。您提供的第一个解决方案不适用于我的系统上的符号链接。
Mike Deck

4
@MikeDeck:第一种解决方案适用于将各种目录符号链接为路径一部分的典型情况,但是如果最终的二进制文件是符号链接,则无济于事。那就是第二个人设法解决的问题。
卡莱布

1
如果脚本文件是sourced,则不起作用(例如$ source ./sript.sh),这在两种情况下均适用:DIR="$(cd "$(dirname "$BASH_SOURCE")" && pwd)"
FractalSpace

7

一条线:

cd $(dirname $([ -L $0 ] && readlink -f $0 || echo $0))

2
一线答案通常不是最有用的。请考虑扩大您的答案以包括进一步支持您建议的解决方案的说明,链接或文档。
HalosGhost 2014年

1
实际上,您不需要这样做,如果根本不涉及符号链接,则原始答案的readlink版本就可以正常工作
THESorcerer


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.