it-swarm.dev

심볼릭 링크없이 상대 경로를 절대 경로로 변환

기호 링크를 포함 할 수있는 상대 경로에서 절대 (및 정규화 된) 경로를 가져 오는 Unix 명령이 있습니까?

66
Benjamin

-f 옵션과 함께 readlink 유틸리티를 사용할 수 있습니다.

-f, --canonicalize

      canonicalize  by  following  every symlink in every component of
      the given name recursively; all  but  the  last  component  must
      exist

예를 들어 GNU coreutilsFreeBSD 를 사용하는 배포판에는 기본적으로 realpath(1) 을 호출하고 거의 수행하는 realpath(3) 유틸리티가 제공됩니다. 같은 것.

83
Mat

PWD variable 은 셸에 의해 현재 디렉토리의 절대 위치로 설정됩니다. 해당 경로의 모든 구성 요소는 심볼릭 링크 일 수 있습니다.

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” "물리적").

일부 유니스는 파일의 "물리적"경로를 인쇄하는 유틸리티를 제공합니다.

  • 합리적으로 최근의 Linux 시스템 (GNU coreutils 또는 BusyBox 사용)은 FreeBSD ≥8.3, NetBSD ≥4.0 및 OpenBSD와 마찬가지로 readlink -f 를 갖습니다. 2.2로.
  • FreeBSD ≥4.3은 realpath 입니다 (일부 Linux 시스템에도 있으며 BusyBox에 있습니다).
  • Perl을 사용할 수 있으면 Cwd module 을 사용할 수 있습니다.

    Perl -MCwd -e 'print Cwd::realpath($ARGV[0])' path/to/file
    

pwd이 (가) 귀하의 필요에 적합합니까? 현재 디렉토리의 절대 경로를 제공합니다. 또는 원하는 것은 realpath () 입니다.

5
xanpeng

alisterrss67 in 이 기사 가장 안정적이고 호환 가능하며 가장 쉬운 방법을 소개합니다. 나는 이것보다 더 나은 방법을 본 적이 없다.

RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`

원래 위치로 돌아가려면

ORGPATH=`pwd`
RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
cd $ORGPATH

또는

RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
cd -

이것이 도움이되기를 바랍니다. 이것은 저에게 가장 큰 해결책이었습니다.

3
Eonil

다른 사람들의 대답을 존중하면서, 나는 아래의 기능이 내가 어디서나 찾은 다른 것보다 리눅스/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
0
lauksas

여기에있는 다른 대답은 훌륭했지만 내 요구에 충분하지 않았습니다. 모든 컴퓨터의 스크립트에서 사용할 수있는 솔루션이 필요했습니다. 내 솔루션은 필요한 스크립트에서 호출 할 수있는 셸 스크립트를 작성하는 것이 었습니다.

#!/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'

스크립트는 두 번째 인수의 경로를 시작점으로 사용하여 첫 번째 인수의 경로를 분석합니다. 첫 번째 인수 만 제공하면 스크립트는 현재 작업 디렉토리에 상대적인 경로를 분석합니다.

0
Sildoreth

또한 추가적으로 $1 (일반적으로 ${PWD}), 다음과 같이 작동합니다.

CWD="${1:-${PredefinedAbsolutePath}}"
if [ "${CWD}" != "${PredefinedAbsolutePath}}" ]; then
    case $1 in
        /*) echo "CWD=${CWD}"; ;;
        *) CWD=$(realpath $1); echo "CWD=${CWD}"; ;;
    esac
fi
0
Nikhil