심볼릭 링크를 포함할 수 있는 상대 경로에서 절대(및 정규화된) 경로를 가져오는 Unix 명령이 있습니까?
답변1
당신은 그것을 사용할 수 있습니다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 핵심 도구그리고FreeBSDrealpath(1)
, 기본적으로 호출만 수행하는 유틸리티 도 함께 제공됩니다.realpath(3)
그리고 거의 똑같은 일을 합니다.
답변2
휴대용으로,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##*/}
심볼릭 링크를 추적하는 이식 가능한 방법은 없습니다. 디렉토리 경로가 있는 경우 대부분의 unices는 $(cd -- "$dir" && pwd -P 2>/dev/null || pwd)
심볼릭 링크를 사용하지 않고 경로를 제공합니다. 심볼릭 링크를 따르는 쉘은 그렇게 하는 경향이 있기 때문입니다 pwd -P
("P"는 "물리적"을 나타냄).
일부 유니스는 파일의 "물리적" 경로를 인쇄하는 유틸리티를 제공합니다.
- 최신 Linux 시스템(GNU coreutils 또는 BusyBox 포함)에는
readlink -f
, FreeBSD ≥8.3, NetBSD ≥4.0 및 OpenBSD 2.2의 경우에도 마찬가지입니다. - FreeBSD ≥4.3 예
realpath
(일부 Linux 시스템에도 존재하며 BusyBox에 있습니다). Perl을 사용할 수 있는 경우 다음을 사용할 수 있습니다.
Cwd
기준 치수.perl -MCwd -e 'print Cwd::realpath($ARGV[0])' path/to/file
답변3
pwd
귀하의 요구에 적합합니까? 현재 디렉터리의 절대 경로를 제공합니다. 아니면 당신이 원하는 것은 아마도실제 경로().
답변4
여기에 있는 다른 답변은 좋지만 내 요구 사항에는 충분하지 않습니다. 모든 컴퓨터의 스크립트에서 사용할 수 있는 솔루션이 필요합니다. 내 해결책은 필요한 스크립트에서 호출할 수 있는 쉘 스크립트를 작성하는 것이었습니다.
#!/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'
스크립트는 두 번째 인수의 경로를 시작점으로 사용하여 첫 번째 인수의 경로를 구문 분석합니다. 첫 번째 인수만 제공되면 스크립트는 현재 작업 디렉터리를 기준으로 경로를 확인합니다.