Исполняемый файл не может найти нужные файлы при вызове через символическую ссылку

Исполняемый файл не может найти нужные файлы при вызове через символическую ссылку

Я создал символическую ссылку на исполняемый файл с помощью

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.

Я предположил, что вопрос касается скрипта оболочки. В других языках могут быть другие методы.


Другой способ решения этой проблемы, который позволяет более или менее полностью избежать ее, — вместо создания символической ссылки на исполняемый файл в вашем пути создать небольшой скрипт, /usr/bin/myexecсодержащий, например,

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

решение2

Я не согласен с @daniel-anderson. Я не думаю, что эти решения правильно учитывают аргументы вызываемой программы. Почти все исполняемые файлы обрабатывают аргументы пути как относительные к текущему каталогу, поэтому даже передача аргументов не сработает.

Единственный случай, когда программа будет вести себя по-другому, если она вызвана из a, symlinkэто если она проверяет 0-й аргумент. Я не знаю способа обойти это с помощью символической ссылки. Простейший способ обойти это — создать промежуточный скрипт оболочки в виде:

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

Обратите внимание, что если по какой-то странной причине вам необходимо указать нулевой аргумент, который на самом деле не находится там, где он есть, вы можете использовать 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

Связанный контент