Как получить «реальный путь» для поиска моей символической ссылки?

Я нахожусь на MacOSX, используя bash как свою оболочку. У меня есть символическая ссылка, созданная вот так:

 ln -s /usr/bin/python python2 

У меня есть пакет, который использует python2, и я хочу создать ссылку на символ в моем текущем рабочем каталоге на /usr/bin/python который на самом деле является python2. Когда я делаю python2 из командной строки, я получаю эту ошибку:

 python2: realpath couldn't resolve "/usr/bin/python2" 

Но ссылаясь на это так ./python2 правильно решает путь. Моя PATH . в этом. На самом деле я изменил его, для тестирования, только для него . в этом.

Как это разрешить? Благодаря!


контекст

Ряд предлагаемых ниже решений не будет работать для меня. Я попытался как можно более тщательно и кратко рассказать о своем вопросе, чтобы люди не утонули в морском тексте, но я должен предоставить больше информации.

Я пытаюсь разработать пакет, который я клонировал из git. Исходный пакет, git-multimail , был / был разработан на каком-то варианте Linux (я предполагаю Ubuntu). Я пытался изменить его, чтобы иметь возможность использовать его и его тестовый набор на MacOSX с минимальными изменениями. Вот почему некоторые из предлагаемых решений не идеальны:

  1. Как root, создайте символическую ссылку python2 в / usr / bin /. Я ищу решение, которое не потребует этого. Это был очевидный вариант в начале, но я хотел бы, чтобы решение, которое как можно меньше модифицирует хост-систему. Вот почему я хотел создать временную символическую ссылку в текущем рабочем каталоге, добавить CWD (т . Е.) В свой путь, а затем уничтожить это, когда закончите (т.е. символическую ссылку).

  2. Создайте скрипт-оболочку, чтобы вызвать скрипт python с существующим python. Проблема заключается в том, что большая часть тестового набора использует фактические скриптовые_файлы в качестве исполняемых файлов, в зависимости от shebang, чтобы найти правильную среду исполнения. Это означало бы значительно облегчить редактирование набора тестов. В этом контексте (см. Ниже фрагмент тестовой среды), мне нужно будет добавить оболочку для каждого .py файла; в дальнейшем пользователь / разработчик должен знать различные правила использования пакета в зависимости от того, в какой системе они находятся (т.е. на MacOSX убедитесь, что вы не используете файлы python, не вызывая их через оболочку или явно вызывающий /usr/bin/python file.py ).

     #! /bin/sh D=$(cd $(dirname "$0") && pwd) MULTIMAIL="$D/../git-multimail/git_multimail.py" POST_RECEIVE="$D/../git-multimail/post-receive" TESTREPO=$("$D/create-test-repo") HOME="$D" XDG_CONFIG_HOME="$D" GIT_CONFIG_NOSYSTEM=1 export HOME XDG_CONFIG_HOME GIT_CONFIG_NOSYSTEM cd $TESTREPO test_email() { REFNAME="$1" OLDREV="$2" NEWREV="$3" echo "$OLDREV" "$NEWREV" "$REFNAME" | USER=pushuser "$MULTIMAIL" } 
  3. Изменение всех ссылок python2 на python . README предлагает это, но это фактически делает управление версиями бесполезным, поскольку система видит изменение как новую версию, когда на самом деле это не (семантически).

Я использовал (3), но я пытаюсь найти лучшее решение. Я согласен с тем, что это так, как есть (т. Е. Нет подходящего способа указать «python2» на /usr/bin/python который является переносимым и ненавязчивым без большого количества изменений в наборе тестов и фактической структуре ).

Если вам нужно разрешить (или расследовать) символическую ссылку, вы можете использовать независимую от платформы библиотеку bash 'realpath-lib'. По умолчанию он эмулирует readlink и будет работать на Mac или Unix. Его можно найти на Github или Bitbucket, и это бесплатно.

Но похоже, что вы хотите просто сделать python2 (а не ./python2) из ​​своего локального (рабочего) каталога. Возможно, это будет возможно с помощью псевдонима в вашем .bashrc, иначе вам нужно будет добавить рабочий каталог (содержащий вашу символическую ссылку) в переменную среды PATH. Это также можно сделать только для текущего сеанса или в файле .bashrc для будущих сеансов. Это может быть решением только для конкретного пользователя.

Другим вариантом, который будет работать для всех пользователей, было бы создание символической ссылки python2 в / usr / bin / python в другой директории на пути, например, в / usr / local / bin. Возможно, что-то вроде:

 sudo ln -s /usr/bin/python /usr/local/bin/python2 

Тогда любой пользователь или скрипт должен найти команды python или python2. Конечно, для этой опции требуются привилегии администратора (root) для установки.

Я считаю, что вы управляете системой Apple для управления и переключения между несколькими версиями одной и той же программы. Вы можете выполнить то, что хотите, менее изящно, но без проблем, со следующим сценарием с именем python2 :

 #!/bin/bash exec /usr/bin/python "$@" 

Сделайте его исполняемым ( chmod +x python2 ), и вы работаете в бизнесе.

Объяснение проблемы:

Когда вы запускаете /usr/bin/python , он находит и выполняет python2.7 в том же каталоге. Ваша символическая ссылка терпит неудачу, потому что система следует символической ссылке в /usr/bin , а затем ищет и не находит там python2 . Вы можете сделать еще один шаг, используя «жесткую ссылку» вместо символической ссылки:

 rm python2 ln /usr/bin/python python2 

Теперь нет никакой символической ссылки, только два имени файла для одного и того же файла (inode). Но теперь я терпеть неудачу со следующим сообщением:

 python2: posix_spawn: /Users/alexis/.../python22.7: No such file or directory 

Обратите внимание на python22.7 : Framework добавляет 2.7 к имени, которое вы создали! Вместо того, чтобы пытаться разгадать это и создать лес ссылок, который соответствует его ожиданиям, я рекомендую вам не обращать внимания на структуру управления версиями и использовать решение, предложенное выше.

PS. Возможно, будет лучшее решение: если вы объясните, что вам нужно сделать, чтобы начать (почему вам нужно предоставить python2 как псевдоним для python ), кто-то, вероятно, может помочь вам сделать это по-другому. Это известно как «проблема XY» в файле stackexchange lingo …

Вы можете использовать readlink для readlink команды Unix, чтобы узнать физический путь ссылок.

Примеры

Скажем, у меня есть следующая ссылка:

 $ ls -l /usr/bin/etags lrwxrwxrwx. 1 root root 29 Dec 10 22:56 /usr/bin/etags -> /etc/alternatives/emacs.etags $ ls -l /etc/alternatives/emacs.etags lrwxrwxrwx. 1 root root 20 Dec 10 22:56 /etc/alternatives/emacs.etags -> /usr/bin/etags.ctags $ ls -l /usr/bin/etags.ctags lrwxrwxrwx. 1 root root 5 Dec 10 22:56 /usr/bin/etags.ctags -> ctags 

  1. Чтобы найти значение, символическая ссылка указывает на

     $ readlink /usr/bin/etags /etc/alternatives/emacs.etags 

    ПРИМЕЧАНИЕ . Вышеуказанный результат может быть другой ссылкой. Чтобы решить эту проблему, см. № 2 ниже.

  2. Чтобы узнать абсолютный путь значения, символическая ссылка указывает на

     $ readlink -f /usr/bin/etags /usr/bin/ctags 

Я не понимаю – как вы считаете, что ссылка на оболочку в порядке, но не сценарий оболочки? Любой из них – только уровень косвенности. И разве вы все равно должны указывать своим пользователям только для вызова его из определенного каталога?

В любом случае, вы можете получить текущий рабочий каталог в $PATH конечно:

  echo "echo \"Hi! I'm python\"" >|./python chmod +x ./python PATH="${PWD}:${PATH}" python #OUTPUT# Hi! I'm python rm python python -V ln -s /usr/bin/python2 ./python python -V #OUTPUT# Python 3.4.0 Python 2.7.6 PATH="${PATH#"${PWD}:"}" python -V #OUTPUT# Python 3.4.0 

Пожалуйста, давай. из вашей $PATH . Это ужасная идея.

Пытаться:

 ln -s /System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7 /usr/local/bin/python2