Я создал символическую ссылку на исполняемый файл с помощью
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