通过符号链接调用时,可执行文件无法找到正确的文件

通过符号链接调用时,可执行文件无法找到正确的文件

我创建了一个可执行文件的符号链接

ln -s /usr/bin/mydir/myexec /usr/bin/myexec

当我myexec在 Bash 中执行时,它不会加载位于原始myexec目录中的正确文件。

为什么会发生这种情况?我该如何解决?我在 Fedora 15 x64 上。

答案1

使用相对路径调用的文件将相对于脚本执行的当前工作目录进行搜索。您的脚本目前可能仅在当前/usr/bin/mydir/myexec执行时才有效。/usr/bin/mydir

解决这个问题的一种方法是给出包含文件的绝对路径(但如果所需文件被移动,则需要更新脚本),或者您需要使用 动态找出绝对路径readlink,例如

THISFILE=$(readlink -f -- "${0}")
THISDIR=${THISFILE%/*}
. "${THISDIR}/my_settings_file"
  • readlink -f将返回符号链接的目标。
  • ${THISFILE%/*}返回符号链接的目标以及包含最后/删除的部分,即相关文件的路径。
  • ${THISDIR}现在包含文件的绝对路径,并且可以像第 3 行那样使用。

我假设问题涉及 shell 脚本。其他语言可能有不同的方法。


另一种解决方法是完全避免这个问题,而不是在路径中对二进制文件进行符号链接,而是创建一个/usr/bin/myexec包含例如

#!/bin/sh
cd /usr/bin/mydir
./myexec

答案2

我不同意@daniel-anderson的观点。我认为这些解决方案没有正确考虑被调用程序的参数。几乎所有可执行文件都将路径参数视为相对于当前目录的参数,因此即使传递参数也行不通。

如果程序从 a 调用,则唯一会出现不同行为的情况symlink是检查第 0 个参数。我不知道如何使用符号链接来解决这个问题。最简单的解决方法是创建一个中间 shell 脚本,格式如下:

#!/bin/sh
/path/to/executable/that/needs/0th/argument/to/be/actual/path $@

请注意,如果由于某些奇怪的原因您需要给它一个实际上并不在那里的第 0 个参数,您可以像这样使用 exec -a:

#!/bin/bash
(exec -a /path/to/executable/to/fool /path/to/fool/executable/with $@)

请注意,“-a”参数可能不是严格的 POSIX 规范,因此我专门使用了 bash。假设您的路径中有一个 ~/bin 文件夹,则第一种(正常)情况可以快速完成,如下所示:

echo -e '#!/bin/sh\n/path/to/executable $@' > ~/bin/shortcut
chmod 755 ~/bin/shortcut
shortcut

相关内容