다음 경로가 동일한 디스크 위치를 가리키나요?
/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/username
inode 번호를 확인하여 동일한 경로인지 확인할 수 없습니다. 이는 디렉토리는 하드 링크될 수 없고 소프트 링크에는 다른 인덱스 노드가 있기 때문입니다.
cd /home/username
파일을 가져와 touch
다른 파일에 나타나는지 확인할 수 있습니다 /app/home/username
. 더 좋은 방법이 있을 수 있으니 더 나은 답변을 주실 수 있는 분이 계시다면 계속 진행해 주시기 바랍니다.