두 디렉터리가 동일한 위치를 가리키는지 확인하는 방법

두 디렉터리가 동일한 위치를 가리키는지 확인하는 방법

다음 경로가 동일한 디스크 위치를 가리키나요?

/home/username
/app/home/username

답변1

차례로 각 디렉토리로 디렉토리를 변경하고 pwd -P-P플래그를 사용하면 pwd확인된 심볼릭 링크와 함께 실제 현재 작업 디렉토리가 표시됩니다.

답변2

두 파일이 동일한지 확인하는 두 가지 기본 방법이 있습니다. 첫 번째는경로가 동일한지 확인하세요.. 오탐은 없지만 오탐이 많습니다. 잘못된 부정의 명백한 사례 중 하나는 기호 링크와 관련이 있습니다. 기호 링크를 해결하여 이 상황을 처리할 수 있습니다. 변경 권한이 있는 기존 디렉터리의 경우 를 사용할 수 있습니다 pwd -P.

absolute_path1="$(cd -- "$path1" && pwd -P; echo .)" &&
absolute_path2="$(cd -- "$path2" && pwd -P; echo .)" &&
[ "$absolute_path1" = "$absolute_path2" ]

추가 내용은 echo .대상 중 하나가 줄 바꿈으로 끝나는 파일 이름을 갖는 드문 경우를 처리합니다. 줄 바꿈이 명령으로 대체된 마지막 문자인 경우 제거되므로 조각이 foo␤와 동일하게 잘못 보고됩니다 foo.

여전히 잠재적인 거짓 부정이 있습니다. 디렉토리의 경우 대부분의 운영 체제와 파일 시스템이 디렉토리 하드 링크를 금지하므로 하드 링크는 문제가 되지 않습니다. 일어날 수 있는 일은 동일한 디렉터리가 어떻게든 다른 위치에서 사용 가능하다는 것입니다. 예를 들면 다음과 같습니다.

  • 동일한 원격 파일 시스템을 서로 다른 두 위치에 마운트합니다.

    mount server:/some/where /mnt1
    mount server:/some/where /mnt2
    compare /mnt1 /mnt2
    
  • 바인드 마운트

  • 스택 가능한 파일 시스템, 즉 파일 시스템을 다른 방식으로 표시하는 시스템으로, 디렉터리 보기가 원래 디렉터리에서 충분히 변경되지 않아 실제로 동일한 디렉터리가 될 수 있습니다. 예를 들어, 스택 가능 파일 시스템은 파일 이름을 변환하고 디렉토리 이름은 변환 후에도 변경되지 않습니다.

이러한 예에서는 디렉터리가 실제로 동일한지 여부에 대해 논쟁의 여지가 있습니다. 이는 극단적인 경우에 "동일 파일" 개념의 한계를 보여줍니다.

두 번째 기본 방법은커널에서 제공한 ID(장치 및 inode)를 확인하세요.. 이것stat시스템 호출각 파일에 대해 두 가지 속성을 보고합니다.

  • 장치 번호( st_dev)는 일반적으로 파일이 있는 파일 시스템이 포함된 블록 장치(디스크 파티션)를 식별합니다.
  • inode 번호( st_ino)는 전통적으로 동일한 파일 시스템 내에서 파일을 식별하는 고유 번호입니다.

일반적으로 두 파일은 동일한 장치 및 inode 번호를 갖는 경우에만 동일합니다. Dash, ksh, bash, zsh 및 적어도 일부 BusyBox 버전(일반 POSIX sh는 아님)에는 모두 다음을 테스트하기 -ef위한 test내장 연산자가 있습니다.

[ "$path1" -ef "$path2" ]

이는 하드 링크와 기호 링크를 올바르게 처리합니다(기호 링크를 따릅니다. 즉, 파일의 기호 링크를 대상 파일과 동일하게 처리합니다).

쉘(또는 test유틸리티)이 이를 지원하는 경우 -ef그러나 모든 파일 시스템이 고유한 inode 번호를 보고하는 것은 아니기 때문에 잘못된 긍정이 있다는 점에 유의하십시오. 예를 들어, 네트워크 파일 시스템의 경우 원격 호스트가 선택한 inode 번호에 따라 달라질 수 있습니다. 많은 스택 가능 파일 시스템은 기본 디렉토리 트리가 여러 파일 시스템에 걸쳐 있는 경우 고유하지 않은 기본 inode를 보고합니다.

다른 접근 방식은관찰 가능한 동등성 테스트: 디렉터리 중 하나를 수정하고 변경 사항이 다른 디렉터리에 반영되는지 확인합니다. 이 접근 방식은 원칙적으로 오탐으로부터 안전하지만 디렉터리를 수정하려면 권한이 필요하며 해당 디렉터리를 사용하는 시스템의 다른 부분을 손상시킬 수 있습니다. 반영된 수정 사항을 보면 디렉터리를 매우 빠르게 동기화하는 데몬이 있음을 나타낼 수 있으므로 잘못된 긍정이 있을 수 있습니다.

답변3

sd(){       set '' "$1" '' "${2?sd() requires two arguments!}"
            while [ "$#" -gt 2 ]
            do    [  "${1:--L}" "${2:--L}" ${3:+"$4"} ] &&
                  [  "${1:--L}" ${3:+"-L"} "${3:-$4}" ] &&
                  [  "${2:-$3}" -ef "$4"/. ] && return  || ${1:+"return"}
                  set "$@" "$2";shift 2;set ! "$@"
            done  3>/dev/null 2>&"$((${#DBG}?2:3))"
    }

sd()먼저 두 인수가 모두 심볼릭 링크인지 확인하고, 그렇다면 두 인수가 동일한 inode 및 장치 번호를 가진 디렉터리에 연결되어 있는지 확인합니다. 그렇다면 sd() return그것은 사실이다

실패하면 둘 다 확인합니다.아니요기호 링크 및 둘 다 동일한 장치 및 inode 번호를 가진 디렉터리인 경우. 실패하면 false를 반환합니다.

그래서...

ln -s dir1 ln3; ln -s dir1 ln4; ln -s dir2 ln5

sd dir1 dir2; echo $?
1
sd dir1 ln3;  echo $?
1
sd ln4 ln3;   echo $?
0
sd ln4 ln5;   echo $?
1
mount --bind dir1 dir2
sd dir1 dir2; echo $?
0

링크 확인을 하지 않는 것이 더 좋습니다. 예를 들어 링크의 대상이 특정 디렉토리와 동일한지 알고 싶거나 링크인지 전혀 신경 쓰지 않는 경우입니다. 이 경우에는 한 번만 테스트하면 됩니다 [ fname1 -ef fname2 ].

아, 이는 모든 매개변수에 대한 검색 권한을 가정한다는 점도 언급해야 할 것 같습니다. 호출 사용자에게 테스트를 실행하는 데 필요한 권한이 없으면 테스트가 실패합니다.

답변4

/home/username및 가 디렉토리라고 가정하면 /app/home/usernameinode 번호를 확인하여 동일한 경로인지 확인할 수 없습니다. 이는 디렉토리는 하드 링크될 수 없고 소프트 링크에는 다른 인덱스 노드가 있기 때문입니다.

cd /home/username파일을 가져와 touch다른 파일에 나타나는지 확인할 수 있습니다 /app/home/username. 더 좋은 방법이 있을 수 있으니 더 나은 답변을 주실 수 있는 분이 계시다면 계속 진행해 주시기 바랍니다.

관련 정보