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

Mik*_*eck 69 bash shell-script symlink

我有一个实用程序,由几个目录组成,其中包含一些 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)
Run Code Online (Sandbox Code Playgroud)

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

Cal*_*leb 96

试试这个作为通用解决方案:

DIR="$(cd "$(dirname "$0")" && pwd)"
Run Code Online (Sandbox Code Playgroud)

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

DIR="$(dirname "$(readlink -f "$0")")"
Run Code Online (Sandbox Code Playgroud)

  • 如果脚本文件是 `source`d 则不起作用(例如 `$ source ./sript.sh`) 这对两种情况都有效: `DIR="$(cd "$(dirname "$BASH_SOURCE")" && pwd )"` (5认同)
  • @MikeDeck:第一个解决方案适用于将各种目录符号链接为路径一部分的典型情况,但如果最终二进制文件是符号链接,则无济于事。这就是第二个设法照顾的东西。 (4认同)
  • 我应该澄清一下,第二个工作完美。您提供的第一个解决方案不适用于我的系统上的符号链接。 (3认同)

小智 9

一条线:

cd $(dirname $([ -L $0 ] && readlink -f $0 || echo $0))
Run Code Online (Sandbox Code Playgroud)

  • 一行答案通常不是最有帮助的。请考虑扩展您的答案以包括进一步支持您建议的解决方案的解释、链接或文档。 (2认同)

小智 5

readlink -f 对我不起作用,我有这个错误:

readlink: illegal option -- f
usage: readlink [-n] [file ...]
Run Code Online (Sandbox Code Playgroud)

但这工作正常:

DIR="$(dirname "$(readlink "$0")")"
echo $DIR
Run Code Online (Sandbox Code Playgroud)

  • 然后你在 Mac 上,[这应该回答你的问题](/sf/ask/73897001/ -苹果电脑)。 (3认同)