В Linux readlink
утилита принимает опцию, -f
которая идет по дополнительным ссылкам. Это не работает на Mac и, возможно, на системах BSD. Каким будет эквивалент?
Вот некоторая отладочная информация:
$ which readlink; readlink -f
/usr/bin/readlink
readlink: illegal option -f
usage: readlink [-n] [file ...]
readlink
может быть встроенной или внешней командой.touch myfile ; ln -s myfile otherfile ; perl -MCwd=abs_path -le 'print abs_path readlink(shift);' otherfile
... в моем случае я вижу: / Users / cito / myfile`. Добавил его в мой ответ ниже. Приветствия.Ответы:
readlink -f
делает две вещи:Если вы хотите, вы можете просто создать сценарий оболочки, который использует ванильное поведение readlink для достижения того же самого. Вот пример. Очевидно, вы могли бы вставить это в свой собственный скрипт, где вы хотели бы позвонить
readlink -f
Обратите внимание, что это не включает обработку ошибок. Особенно важно, что он не обнаруживает циклы символических ссылок. Простой способ сделать это - посчитать, сколько раз вы обойдете цикл и потерпите неудачу, если наберете невероятно большое число, например 1000.
ИЗМЕНЕНО для использования
pwd -P
вместо$PWD
.Обратите внимание, что этот сценарий будет вызываться как
./script_name filename
, нет-f
, изменится$1
на,$2
если вы хотите иметь возможность использовать-f filename
подобную GNU readlink.источник
foo -> /var/cux
, тоfoo/bar
не будет решен, потому чтоbar
это не ссылка, хотяfoo
есть.cd "$(dirname "$TARGET_FILE")"
иTARGET_FILE=$(readlink "$TARGET_FILE")
иTARGET_FILE=$(basename "$TARGET_FILE")
в соответствующих местах в приведенном выше коде.MacPorts и Homebrew предоставляют пакет coreutils , содержащий
greadlink
(GNU readlink). Благодарим Майкла Каллвейта от mackb.com.источник
.bashrc
:export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
pwd -P
иreadlink
на OS X, не устанавливая ничегоPATH
. Сделал выше, начиная сbrew install <package> --default-names
. Много раз на вопрос на этом сайте отвечали немного, или более того, за пределами технических требований автора, но в аналогичной ситуации, и все еще был очень полезен. topbug.net/blog/2013/04/14/…Вас могут заинтересовать
realpath(3)
или Pythonos.path.realpath
. Два не совсем то же самое; вызов библиотеки C требует, чтобы компоненты промежуточного пути существовали, а версия Python - нет.Я знаю, что вы сказали, что предпочтете что-то более легкое, чем другой язык сценариев, но на случай, если компиляция двоичного файла является невыносимой, вы можете использовать Python и ctypes (доступные в Mac OS X 10.5) для переноса вызова библиотеки:
По иронии судьбы версия C этого скрипта должна быть короче. :)
источник
realpath
это действительно то, чего я хочу. Но кажется довольно неловким, что мне нужно скомпилировать двоичный файл, чтобы получить эту функцию из сценария оболочки.readlink
себе, не так ли?)python -c "import os,sys; print(os.path.realpath(os.path.expanduser(sys.argv[1])))" "${1}"
работает с путями, как'~/.symlink'
perl -MCwd=abs_path -le 'print abs_path readlink(shift);'
к своему ответу :-)Ненавижу накапливать еще одну реализацию, но мне понадобились: а) портативная реализация с чистой оболочкой и б) охват модульным тестом , так как количество граничных случаев для чего-то подобного нетривиально .
Смотрите мой проект на Github для тестов и полного кода. Далее следует краткий обзор реализации:
Как со всей проницательностью указывает Кит Смит, он
readlink -f
делает две вещи: 1) рекурсивно разрешает символические ссылки и 2) канонизирует результат, следовательно:Во-первых, реализация распознавателя символической ссылки:
Обратите внимание, что это слегка упрощенная версия полной реализации . Полная реализация добавляет небольшую проверку циклов символической ссылки , а также немного массирует вывод.
Наконец, функция для канонизации пути:
Вот и все, более или менее. Достаточно простой для вставки в ваш скрипт, но достаточно хитрый, чтобы вы с ума сошли, полагаясь на любой код, не имеющий модульных тестов для ваших сценариев использования.
источник
local
ключевое слово не POSIXreadlink -f
ниrealpath
. Предполагая, что Mac с установленной формулой coreutils (то есть сgreadlink
доступной), попробуйте это сln -s /tmp/linkeddir ~/Documents
;greadlink -f /tmp/linkeddir/..
печатает ваш домашний каталог (он разрешил/tmp/linkeddir
ссылку перед применением..
родительской ссылки dir), но ваш код выдает/private/tmp/
as/tmp/linkeddir/..
не символическую ссылку, а значение-d /tmp/linkeddir/..
true, и поэтомуcd /tmp/linkeddir/..
вы переходите к тому/tmp
, чей канонический путь есть/private/tmp
. Ваш код делает тоrealpath -L
, что делает, вместо этого.Простой однострочный в Perl, который будет работать практически везде без каких-либо внешних зависимостей:
Будет разыменовывать символические ссылки.
Использование в скрипте может быть таким:
источник
-l
perl -MCwd -le 'print Cwd::abs_path shift' ~/non-absolute/file
greadlink - это ссылка для чтения gnu, которая реализует -f. Вы можете использовать MacPort или другие, я предпочитаю доморощенный.
источник
Я сделал скрипт под названием realpath лично, который выглядит примерно так:
источник
sys.argv[1]
если вы хотите, чтобы скрипт печатал реальный путь первого аргумента.sys.argv[0]
просто печатает реальный путь самого скрипта pyton, что не очень полезно.~/.profile
:alias realpath="python -c 'import os, sys; print os.path.realpath(sys.argv[1])'"
readlink -f
, вот модифицированная версия псевдонима @jwhitlock для поддержки возможного-f
флага:alias realpath="python -c 'import os, sys; print os.path.realpath(sys.argv[2] if sys.argv[1] == \"-f\" else sys.argv[1])'"
Что насчет этого?
источник
../../../
->/
/usr/bin/
например, какalternatives
система любит иметь.Вот портативная функция оболочки, которая должна работать в любой похожей оболочке Bourne. Это разрешит пунктуацию относительного пути ".. или." и разыменование символических ссылок.
Если по какой-либо причине у вас нет команды realpath (1) или readlink (1), это может быть псевдоним.
Наслаждаться:
Кроме того, на случай, если кто-то заинтересован, вот как реализовать basename и dirname в 100% чистом шелл-коде:
Вы можете найти обновленную версию этого шелл-кода на моем сайте Google: http://sites.google.com/site/jdisnard/realpath
РЕДАКТИРОВАТЬ: Этот код лицензируется в соответствии с условиями 2-пунктовой (стиль FreeBSD) лицензии. Копию лицензии можно найти, перейдя по указанной выше гиперссылке на мой сайт.
источник
FreeBSD и OSX имеют версию,
stat
производную от NetBSD.Вы можете настроить вывод с помощью переключателей формата (см. Страницы руководства по ссылкам выше).
Некоторые версии OS X
stat
могут не иметь-f%R
опции для форматов. В этом случае-stat -f%Y
может быть достаточно.-f%Y
Вариант будет показывать цель символьной ссылки, в то время как-f%R
показывает абсолютный путь , соответствующий файл.РЕДАКТИРОВАТЬ:
Если вы можете использовать Perl (Darwin / OS X поставляется с последними версиями
perl
), то:будет работать.
источник
R
Возможность-f%
отсутствует. Возможно,stat -f%Y
дает желаемый результат. Я буду корректировать ответ. Обратите внимание, чтоstat
инструмент появился во FreeBSD в версии 4.10 и NetBSD в версии 1.6.Самый простой способ решить эту проблему и включить функциональность readlink на Mac с установленным Homebrew или FreeBSD - это установить пакет 'coreutils'. Может также потребоваться в некоторых дистрибутивах Linux и других ОС POSIX.
Например, во FreeBSD 11 я установил, вызвав:
# pkg install coreutils
На MacOS с Homebrew команда будет такой:
$ brew install coreutils
Не совсем уверен, почему другие ответы такие сложные, вот и все, что нужно сделать. Файлы не находятся в другом месте, они просто еще не установлены.
источник
brew install coreutils --with-default-names
быть более конкретным. Или вместо этого вы получите «greadlink» ...pwd -P
довольно просто, но он исчезает среди многих других ответов, в том числе повторяющихся, отсюда и отрицательный ответ.Начать обновление
Это настолько частая проблема, что мы собрали библиотеку Bash 4 для бесплатного использования (лицензия MIT), которая называется realpath-lib . Это разработано для эмуляции readlink -f по умолчанию и включает в себя два набора тестов для проверки (1), что он работает для данной системы Unix, и (2) против readlink -f, если он установлен (но это не обязательно). Кроме того, его можно использовать для исследования, выявления и разматывания глубоких, поврежденных символических ссылок и циклических ссылок, поэтому он может быть полезным инструментом для диагностики глубоко вложенных физических или символических проблем с каталогами и файлами. Его можно найти на github.com или bitbucket.org .
Конец обновления
Другое очень компактное и эффективное решение, которое не полагается ни на что, кроме Bash:
Это также включает параметр среды,
no_symlinks
который предоставляет возможность разрешать символические ссылки на физическую систему. Покаno_symlinks
установлено что-то, то есть,no_symlinks='on'
тогда символические ссылки будут разрешены для физической системы. В противном случае они будут применены (настройка по умолчанию).Это должно работать в любой системе, которая предоставляет Bash, и будет возвращать Bash-совместимый код завершения для целей тестирования.
источник
Ответов уже много, но у меня не получилось ни одного ... Так что я сейчас и пользуюсь.
источник
$target
путь, это работает, только если это файл.Ленивый способ, который работает для меня,
источник
Наверное, лучше поздно, чем никогда. Я был мотивирован, чтобы разработать это специально, потому что мои скрипты Fedora не работали на Mac. Проблема в зависимостях и Bash. У Mac их нет, или, если они есть, они часто находятся где-то еще (другой путь). Манипулирование путями зависимости в кроссплатформенном скрипте Bash в лучшем случае является головной болью, а в худшем - угрозой безопасности, поэтому лучше по возможности избегать их использования.
Функция get_realpath () ниже проста, ориентирована на Bash, и никаких зависимостей не требуется. Я использую только встроенные в Bash echo и cd . Это также довольно безопасно, так как все проверяется на каждом этапе пути и возвращает ошибки.
Если вы не хотите переходить по символическим ссылкам, поместите set -P в начало сценария, но в противном случае cd должен разрешить символические ссылки по умолчанию. Это было проверено с аргументами файла, которые являются {absolute | родственник | символическая ссылка | local} и возвращает абсолютный путь к файлу. До сих пор у нас не было никаких проблем с этим.
Вы можете комбинировать это с другими функциями get_dirname, get_filename, get_stemname и validate_path. Их можно найти в нашем репозитории GitHub как realpath-lib (полное раскрытие информации - это наш продукт, но мы предлагаем его бесплатно для сообщества без каких-либо ограничений). Он также может служить инструктивным инструментом - он хорошо документирован.
Мы старались изо всех сил применять так называемые практики «современного Bash», но Bash - это важная тема, и я уверен, что всегда найдется место для улучшения. Требуется Bash 4+, но его можно настроить для работы со старыми версиями, если они все еще существуют.
источник
Так как моя работа используется людьми с не-BSD Linux, а также с macOS, я решил использовать эти псевдонимы в наших скриптах сборки (в том
sed
числе из-за схожих проблем):Дополнительная проверка, которую вы можете добавить для автоматической установки зависимостей homebrew + coreutils :
Я полагаю, что он действительно «глобальный», он должен проверять других ... но это, вероятно, близко к отметке 80/20.
источник
объяснение
Coreutils является
brew
пакет, который устанавливает основные утилиты GNU / Linux, соответствующие их реализации в Mac OSX, чтобы вы могли использовать ихВы можете найти программы или утилиты в вашей системе Mac OSX, которые кажутся похожими на Linux coreutils («Утилиты ядра»), но в некоторых случаях они различаются (например, имеют разные флаги).
Это потому, что реализация этих инструментов в Mac OSX отличается. Чтобы получить исходное поведение, подобное GNU / Linux, вы можете установить
coreutils
пакет через системуbrew
управления пакетами.Это установит соответствующие основные утилиты с префиксом
g
. Напримерreadlink
, вы найдете соответствующуюgreadlink
программу.Для того, чтобы заставить
readlink
работать как реализация GNUreadlink
(greadlink
), вы можете создать простой псевдоним после установки coreutils.Реализация
Следуйте инструкциям на https://brew.sh/
brew install coreutils
Вы можете поместить свой псевдоним в ~ / .bashrc, ~ / .bash_profile или в любое место, где вы храните псевдонимы bash. Я лично держу свои в ~ / .bashrc
alias readlink=greadlink
Вы можете создать аналогичные псевдонимы для других coreutils, таких как gmv, gdu, gdf и так далее. Но имейте в виду, что поведение GNU на компьютере Mac может сбивать с толку других, привыкших работать с нативным coreutils, или может вести себя неожиданно в вашей системе Mac.
источник
Я написал утилиту realpath для OS X, которая может дать те же результаты, что и
readlink -f
.Вот пример:
Если вы используете MacPorts, вы можете установить его с помощью следующей команды:
sudo port selfupdate && sudo port install realpath
.источник
По-настоящему независимым от платформы будет и этот R-onliner
Чтобы фактически имитировать
readlink -f <path>
, нужно было бы использовать 2 доллара вместо 1 доллара.источник
POSIX-совместимая
readlink -f
реализация для сценариев оболочки POSIXhttps://github.com/ko1nksm/readlinkf
Это POSIX-совместимый (без bashism). Это не использует ни,
readlink
ниrealpath
. Я проверил, что это точно так же, сравнивая с GNUreadlink -f
(см. Результаты теста ). Имеет обработку ошибок и хорошую производительность. Вы можете смело заменить сreadlink -f
. Лицензия является CC0, поэтому вы можете использовать ее для любого проекта.Пожалуйста, обратитесь к последнему коду. Это может быть исправлено.
источник
В Perl есть функция readlink (например, Как мне скопировать символические ссылки в Perl? ). Это работает на большинстве платформ, включая OS X:
Например:
источник
readlink
без-f
опции - без рекурсии, без абсолютного пути - так что вы можете также использоватьreadlink
напрямую.Ответ от @Keith Smith дает бесконечный цикл.
Вот мой ответ, который я использую только в SunOS (SunOS пропускает так много команд POSIX и GNU).
Это файл сценария, который вы должны поместить в один из ваших каталогов $ PATH:
источник
Это то, что я использую:
stat -f %N $your_path
источник
Пути к readlink различны между моей системой и вашей. Пожалуйста, попробуйте указать полный путь:
источник
readlink
которая совместима с GNU. Приятно знать, но это не решает мою проблему, так как мне нужно, чтобы мой скрипт запускался на машине других людей, и я не могу требовать от них установки fink для этого.