Можно использовать readlink
утилита, с -f
опция:
-f, --canonicalize
canonicalize by following every symlink in every component of the given name recursively; all but the last component must exist
Некоторые дистрибутивы, например, те, которые используют GNU coreutils и FreeBSD, также идут с a realpath(1)
утилита, которая в основном просто звонит realpath(3)
и делает в значительной степени то же самое.
Портативно, PWD
переменная установлена оболочкой на одно абсолютное местоположение текущего каталога. Любой компонент того пути может быть символьной ссылкой.
case $f in
/*) absolute=$f;;
*) absolute=$PWD/$f;;
esac
Если Вы хотите устранить .
и ..
также, изменитесь на каталог, содержащий файл, и получите $PWD
там:
if [ -d "$f" ]; then f=$f/.; fi
absolute=$(cd "$(dirname -- "$f")"; printf %s. "$PWD")
absolute=${absolute%?}
absolute=$absolute/${f##*/}
Нет никакого портативного способа перейти по символьным ссылкам. Если у Вас есть путь к каталогу, то на большинстве нельдов $(cd -- "$dir" && pwd -P 2>/dev/null || pwd)
обеспечивает путь, который не использует символьные ссылки, потому что оболочки, которые отслеживают символьные ссылки, имеют тенденцию реализовывать pwd -P
(“P” для “физического”).
Некоторые нельды обеспечивают утилиту для печати “физического” пути к файлу.
readlink -f
также как и FreeBSD ≥8.3, NetBSD ≥4.0 и OpenBSD еще 2.2.realpath
(это также присутствует в некоторых системах Linux, и это находится в BusyBox).Если Perl доступен, можно использовать Cwd
модуль.
perl -MCwd -e 'print Cwd::realpath($ARGV[0])' path/to/file
pwd
($(cd -- "$dir" && pwd -P 2>/dev/null | pwd)
)? Это, кажется, не заботится о stdin.
– Mateusz Piotrowski
17.03.2017, 01:39
pwd
подходящий для Ваших потребностей? Это дает полный путь текущего каталога. Или возможно то, что Вы хотите, является realpath ().
alister
и rss67
в этой статье представляют самый стабильный, совместимый и самый легкий путь. Я никогда замечаемый лучший путь, чем это прежде.
RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
Если Вы хотите вернуться к исходному местоположению,
ORGPATH=`pwd`
RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
cd $ORGPATH
или
RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
cd -
Я желаю, чтобы это помогло. Это было самым большим решением для меня.
ABSPATH=$(cd -- "$RELPATH" && pwd)
. Отметьте двойные кавычки вокруг замены (чтобы не повредиться, если путь содержит пробел и globbing символы), и --
(в случае, если путь начинается -
). Также это только работает на каталоги и не канонизирует символьные ссылки согласно просьбе. Дополнительную информацию см. в моем ответе.
– Gilles 'SO- stop being evil'
27.09.2012, 11:49
Остальные ответы здесь были в порядке, но были недостаточны для моих нужд. Мне нужно было решение, которое я мог бы использовать в своих скриптах на любой машине. Моим решением было написать сценарий оболочки, который я мог бы использовать в скриптах там, где мне это нужно.
#!/bin/sh
if [ $# -eq 0 ] || [ $# -gt 2 ]; then
printf 'Usage: respath path [working-directory]\n' >&2
exit 1
fi
cantGoUp=
path=$1
if [ $# -gt 1 ]; then
cd "$2"
fi
cwd=`pwd -P` #Use -P option to account for directories that are actually symlinks
#Handle non-relative paths, which don't need resolution
if echo "$path" | grep '^/' > /dev/null ; then
printf '%s\n' "$path"
exit 0
fi
#Resolve for each occurrence of ".." at the beginning of the given path.
#For performance, don't worry about ".." in the middle of the path.
while true
do
case "$path" in
..*)
if [ "$cwd" = '/' ]; then
printf 'Invalid relative path\n' >&2
exit 1
fi
if [ "$path" = '..' ]; then
path=
else
path=`echo "$path" | sed 's;^\.\./;;'`
fi
cwd=`dirname $cwd`
;;
*)
break
;;
esac
done
cwd=`echo "$cwd" | sed 's;/$;;'`
if [ -z "$path" ]; then
if [ -z "$cwd" ]; then
cwd='/'
fi
printf '%s\n' "$cwd"
else
printf '%s/%s\n' "$cwd" "$path"
fi
Это решение написано для Bourne Shell для переносимости. У меня это есть в скрипте под названием "respath.sh".
Этот скрипт можно использовать следующим образом:
respath.sh '/path/to/file'
Или вот так
respath.sh '/relative/path/here' '/path/to/resolve/relative/to'
Скрипт разрешает путь в первом аргументе, используя путь от второго аргумента в качестве отправной точки. Если предоставлен только первый аргумент, то сценарий разрешает путь относительно вашей текущей рабочей директории.
Предположим, что переменная a хранит имя пути (a = "что угодно")
1. Для потенциального пути, содержащего пробелы:
c = $ (grep -o "" <<< $ a | wc -l); если (($ c> "0")); тогда a = $ (sed 's / / \\ / g' <<< $ a); fi
2. Что касается фактического вопроса, то есть преобразования пути в абсолютный: readlink может получить содержимое символической ссылки, которое можно использовать следующим образом. (примечание readlink -f
было бы идеально, но он недоступен по крайней мере в Mac OS X bash, в котором -f означает FORMATS .)
если [[$ (readlink $ a) == ""]]; тогда a = $ (cd $ a; pwd); иначе a = $ (cd $ (readlink $ a); pwd); fi
3. Только что изучил pwd -P
в man pwd
: -P означает « Показать физический текущий рабочий каталог (все символьные ссылки разрешены) » и, следовательно,
if (($ (grep -o "" <<< $ a | wc -l)> "0")); тогда a = $ (sed 's / / \\ / g' <<< $ a); fi; a = $ (cd $ a; pwd -P)
тоже подойдет.
Заключение: объедините 1 с 2 , чтобы удовлетворить оба ваших требования, в то время как имена путей, содержащие пробелы, уже учтены в более кратком 3 .
Если, кроме того, у вас есть предопределенный путь для $1
(, обычно ${PWD}
), будет работать следующее:
CWD="${1:-${PredefinedAbsolutePath}}"
if [ "${CWD}" != "${PredefinedAbsolutePath}}" ]; then
case $1 in
/*) echo "CWD=${CWD}"; ;;
*) CWD=$(realpath $1); echo "CWD=${CWD}"; ;;
esac
fi
Уважая все остальные ответы, я обнаружил, что функция ниже очень проста и переносима между linux / MAC OSX, чем другие, которые я нашел повсюду. Может поможет кому.
#!/usr/bin/bash
get_absolute_path(){
file_path=`pwd $1`
echo "$file_path/$1"
}
#to assign to a variable
absolute_path=$(get_absolute_path "file.txt")
echo $absolute_path
-f
переключатель не существует на Mac OS X (по крайней мере, с 10.8.5). Без-f
переключитесь это просто возвращает код ошибки. – iconoclast 27.09.2013, 05:43readlink
ниrealpath
– Солярис и HP-UX, в частности. – Sildoreth 22.05.2015, 18:09