透過符號連結呼叫時可執行檔找不到正確的文件

透過符號連結呼叫時可執行檔找不到正確的文件

我使用以下命令創建了到可執行文件的符號鏈接

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

相關內容