파일이 하드 링크인지 아니면 심볼릭 링크인지 확인하고 있습니까?


51

파일의 파일 이름 / 경로를 가져 와서 파일이 기호 링크인지 하드 링크인지를 결정하는 쉘 스크립트를 작성 중입니다.

유일한 것은, 그들이 그들이 하드 링크인지 확인하는 방법을 모른다는 것입니다. 테스트 파일로 사용하기 위해 두 개의 파일 (하나는 하드 링크와 하나는 기호 링크)을 만들었습니다. 그러나 파일이 쉘 스크립트 내에서 하드 링크인지 또는 기호인지 어떻게 알 수 있습니까?

또한 심볼릭 링크의 대상 파티션을 어떻게 찾을 수 있습니까? 다른 파티션으로 연결되는 파일이 있다고 가정하면 해당 원본 파일의 경로를 어떻게 찾을 수 있습니까?


16
하드 링크는 무엇을 의미합니까? 모든 파일은 하드 링크입니다.
terdon

1
@terdon ln /foo/bar/ /foo/bar2ln -s /foo/bar /foo/bar2심볼릭 링크를 만드는 동안 하드 링크를 만듭니다.
DisplayName

14
@DisplayName 예, 그러나 모든 파일은 inode에 대한 하드 링크입니다. 이것이 리눅스 파일 시스템의 작동 방식입니다. 당신의 예에서 bar2bar똑같이 아이 노드를 가리키는 모두 하드 링크입니다.
terdon

10
@DisplayName 예, 다른 inode에 대한 하드 링크 입니다. 여기에는 모순이 없습니다. 파일은 inode에 대한 링크입니다. 이것이 파일의 정의입니다. 귀하의 경우에는 다른 위치에 이러한 링크가 있지만 기본 데이터 구조는 변경되지 않습니다. 내 요점은 둘이다 bar그리고 bar2동등하게 중요하다. 하나는 다른 하나에 대한 링크가 아니며 둘 다 링크이지만 동일한 inode를 가리 킵니다.
terdon

3
@Scott 아니오, 일반 파일은 하드 링크이며 생성 된 하드 링크는 일반 파일과 ln다르지 않습니다.
terdon

답변:


42

사용하여 짐의 대답은 심볼릭 링크를 테스트하는 방법에 대해 설명 test의 ' -L테스트를.

그러나 "하드 링크"에 대한 테스트는 엄격하게 원하는 것이 아닙니다. 하드 링크는 Unix가 파일을 처리하는 방식 때문에 작동합니다. 각 파일은 단일 inode로 표시됩니다. 그런 다음 단일 inode에는 0 개 이상의 이름 또는 디렉토리 항목 또는 기술적으로 하드 링크 ( "파일"이라고 함)가 있습니다.

고맙게도이 stat명령은 가능한 경우 inode의 이름 수를 알려줍니다.

그래서 당신은 이와 같은 것을 찾고 있습니다 (여기서 GNU 또는 busybox 구현을 가정 stat) :

if [ "$(stat -c %h -- "$file")" -gt 1 ]; then
    echo "File has more than one name."
fi

-c '%h'비트는 말한다 stat즉, 아이 노드에 바로 출력 하드 링크의 수를, 파일이 이름의 수. -gt 1그런 다음 1보다 큰지 확인합니다.

다른 파일과 마찬가지로 심볼릭 링크를 여러 디렉토리에 연결할 수 있으므로 하나의 심볼릭 링크에 여러 개의 하드 링크를 만들 수 있습니다.


좋아, 분명히하기 위해, 파일이 stat 명령을 사용하여 가지고있는 하드 링크 수를 출력 할 수 있으며 그보다 1보다 크면 파티션의 어딘가에 다른 파일이 링크되어 있습니다.
k-Rocker

@ k-Rocker 예. 그런 다음 파티션 어딘가에 두 번째 이름이 있습니다.
derobert

1
OS X 또는 * BSD에서는 stat -f %l /path/to/file입니다. gstat -c %h /path/to/file기본 이름없이 (OS X의 Homebrew 사용) GNU coreutils를 설치 한 경우 에도 사용할 수 있습니다 .
GDP2

29

예를 들면 :

$ touch f1
$ ln f1 f2
$ ln f1 f3
$ ln -s f1 s1
$ ln -s f2 s2
$ ln -s ./././f3 s3
$ ln -s s3 s4
$ ln s4 s5
$ ls -li
total 0
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 f1
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 f2
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 f3
10802345 lrwxrwxrwx 1 stephane stephane 2 Nov 12 19:56 s1 -> f1
10802346 lrwxrwxrwx 1 stephane stephane 2 Nov 12 19:56 s2 -> f2
10802347 lrwxrwxrwx 1 stephane stephane 8 Nov 12 19:56 s3 -> ./././f3
10802384 lrwxrwxrwx 2 stephane stephane 2 Nov 12 19:56 s4 -> s3
10802384 lrwxrwxrwx 2 stephane stephane 2 Nov 12 19:56 s5 -> s3

f1, f2f3디렉토리 항목은 같은 파일 (같은 아이 노드 : 10802124, 당신의 수를 알 수있는 링크 3). 그들은 동일한 일반 파일 에 대한 하드 링크 입니다.

s4s5같은 파일 (10802384)입니다. 이것은 정규적인 것이 아니라 symlink 타입 입니다. 그들은 여기서 길을 가리킨다 s3. s4s5동일한 디렉토리의 항목 이므로 해당 상대 경로 s3는 둘 다에 대해 동일한 파일 (inod 10802347이있는 파일)을 가리 킵니다.

를 수행하는 경우 ls -Ll심볼릭 링크를 해결 한 후 파일 정보를 요청합니다.

$ ls -lLi
total 0
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 f1
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 f2
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 f3
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 s1
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 s2
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 s3
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 s4
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 s5

당신은 그들이 모두 찾을 수 있습니다 해결 같은 파일 (10802124)에.

파일이과의 심볼릭 링크인지 확인할 수 있습니다 [ -L file ]. 마찬가지로 파일이로 일반 파일인지 테스트 할 수 [ -f file ]있지만이 경우 심볼릭 링크를 확인한 후 검사가 수행됩니다.

하드 링크는 파일 형식이 아니며 파일 형식이 다른 파일 이름 일뿐입니다.


19

명령 의 -h-L연산자 사용 test:

-h file 
true if file is a symbolic link

-L file 
true if file is a symbolic link

http://www.mkssoftware.com/docs/man1/test.1.asp

이 SO 스레드 에 따르면 동일한 동작을 갖지만 -L선호됩니다.


좋아,하지만 하드 링크는 어때? 트레드를 확인했지만 하드 링크에 대해서는 아무것도 없습니다. -L이 false를 리턴하면 하드 링크를 의미합니까? 아니면 그냥 일반 파일입니까?
k-Rocker 17

1
하드 링크는 동일 inode합니다. 또한 소프트 링크 lls -l출력 의 시작 부분에 표시됩니다 ... 스크립트에 규칙을 결합 [[ -L file ]]하고 주어진 파일이 소프트 인지 하드 인지 테스트 할 수 있다고 생각합니다 .
jimm-cl

또한 심볼릭 링크의 대상 파티션을 어떻게 찾을 수 있습니까?
k-Rocker

3

여기에는 많은 정답이 있지만 아무도 원래의 오해를 실제로 해결했다고 생각하지 않습니다. 원래의 질문은 기본적으로 "심볼릭 링크를 만들면 나중에 쉽게 식별 할 수 있습니다. 그러나 하드 링크를 식별하는 방법을 알 수 없습니다." 그렇습니다. 대답은 기본적으로 "당신은 할 수 없습니다"로 요약되며 그 이유를 설명 할 수는 있지만 아무도 혼란스럽고 이상하다고 인정한 사람은 없습니다.

이 모든 것을 읽고 있고 무슨 일이 일어나고 있는지 알아 낸다면 좋습니다. 내 작은 글을 읽을 필요가 없습니다. 여전히 혼란 스러우면 계속 진행하십시오.

정말 짧은 대답은 하드 링크는 실제로 링크가 아니라 상징적 링크가 아니라는 것입니다. 디렉토리 구조에서 새 디렉토리는 원래 디렉토리 항목과 동일한 바이트 수를 가리키며 일단 생성하면 첫 번째 항목과 마찬가지로 '실제'이며 합법적입니다. 드라이브의 모든 '일반'파일에는 하나 이상의 하드 링크가 있습니다. 그없이, 당신은 그것을 볼 것입니다 어떤디렉토리를 참조하거나 참조 할 수 없습니다. 따라서 Fred.txt 파일이 있고 Wilma.txt와 Barney.txt를 하드 링크로 연결하면 세 이름 (및 디렉토리 항목)이 모두 동일한 파일을 참조하며 모두 동일하게 유효합니다. 텍스트 편집기에서 "저장"을 눌렀을 때 항목 중 하나가 생성되었고 "ln"명령으로 다른 항목이 작성되었다는 것을 OS가 알 수있는 방법은 없습니다.

그러나 OS 동일한 파일을 가리키는 다른 항목 수를 추적해야합니다. Wilma.txt를 삭제하면 드라이브의 여유 공간을 확보하지 않아도됩니다. 그러나 Fred.txt ( '원본'파일)를 삭제하면 Fred.txt로 알려진 드라이브의 데이터도 여전히 Barney.txt이기 때문에 드라이브의 공간을 확보하지 않아도됩니다. 모든 디렉토리 항목 을 삭제 하는 경우에만 OS가 데이터 자체가 차지하고 있던 공간을 할당 해제합니다.

Barney.txt이 심볼릭 링크 있었다면, 다음 Fred.txt은 삭제 공간을 할당 해제했고, Barney.txt 이제 깨진 링크가 될 것입니다. 또한 심볼릭 링크가 가리키는 파일을 이동하거나 이름을 바꾸면 링크가 끊어집니다. 그러나 파일 / 데이터를 가리키는 다른 디렉토리 항목을 손상시키지 않고 원하는대로 하드 링크 된 파일을 이동하거나 이름을 바꿀 수 있습니다. 모든 파일은 드라이브에서 동일한 데이터 블록을 참조하는 디렉토리 항목이기 때문입니다. 해당 데이터의 inode 번호).

[그것은 2 년 후, 그리고 마지막 비트 혼란 나를 잠깐, 그래서 내가 분명히 것 같아요. "mv ./Wilma.txt ../elsewhere/Betty.txt"를 입력하면 파일을 옮기는 것처럼 보이지만 실제로는 그렇지 않습니다. 실제로하고있는 것은 현재 디렉토리의 디렉토리 목록에서 'Wilma.txt'라는 이름이 inode ######를 사용하여 찾을 수있는 데이터와 연결되어있는 광고 항목을 제거하는 것입니다. #, "및 'Betty.txt'라는 이름이 inode #######"를 통해 찾을 수있는 데이터와 연결되어있는 디렉토리 ../elsewhere의 디렉토리 목록에 새 광고 항목 추가 그렇기 때문에 동일한 드라이브의 다른 위치로 이동하는 한 2 기가 바이트 파일만큼 2 기가 바이트 파일을 '이동'할 수 있습니다.]

OS가 동일한 데이터 덩어리를 가리키는 얼마나 많은 다른 디렉토리 항목을 추적 할 수 있기 때문에, 당신은 할 수 있습니다 특정 파일이 하드에 연결되어있는 경우, 확실히 말할 수는 없지만, 이야기 디렉토리 항목이 만약 당신이 '보고있는 것은'원본 '입니다. 한 가지 방법은 "ls"명령, 특히 "ls -l"입니다 (대시 뒤에 소문자 L 임)

이전 예를 빌리려면 ...

 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 f1

첫 번째 문자는 대시이므로 디렉토리 나 다른 이국적인 것이 아니며 '일반적인'일반 파일입니다. 그러나 실제로 평범한 경우, rwx-ish 부분 다음의 숫자는 "1"이됩니다. "이 데이터 블록을 가리키는 디렉토리 항목이 하나 있습니다." 그러나 이것은 하드 링크 시연의 일부이므로 "3"으로 표시됩니다.

이것은 이상하고 신비한 행동으로 이어질 수 있습니다 (하드 링크에 머리를 감지 않은 경우). 텍스트 편집기에서 Fred.txt를 열고 약간 변경하면 Wilma.txt와 Barney.txt에서도 동일하게 변경됩니까? 아마도. 아마. 텍스트 편집기에서 원본 파일을 열고 변경 내용을 기록하여 변경 내용을 저장하면 세 이름이 모두 동일한 (새로 변경된) 텍스트를 가리 킵니다. 그러나 텍스트 편집기가 새 파일 (Fred-new-temp.txt)을 작성하고 변경된 버전을 해당 파일에 쓴 다음 Fred.txt를 삭제 한 다음 Fred-new-temp.txt의 이름을 Fred.txt로 바꾸면 Wilma와 Barney는 변경된 새 버전이 아닌 원래 버전을 계속 가리 킵니다. 하드 링크를 이해하지 못하면 약간 화가 날 수 있습니다. :) [좋아요, 저는 개인적으로 아무것도 몰라요새 파일 / 이름 바꾸기 작업을 수행하는 텍스트 편집기 를 사용하지만 정확하게 수행하는 다른 프로그램은 많이 알고 있으므로주의하십시오.]

마지막 참고 사항 : 'fsck'(파일 시스템 검사)가 확인하는 것 중 하나는 드라이브에 데이터가 더 이상 디렉토리 항목에 의해 참조되지 않는 데이터 블록이 있는지 여부입니다. 때때로 문제가 발생하여 inode를 가리키는 유일한 디렉토리 항목이 삭제되지만 드라이브 공간 자체는 "사용 가능"으로 표시되지 않습니다. 따라서 fsck의 작업 중 하나는 할당되지 않은 모든 공간을 모든 디렉토리 항목과 일치시켜 참조되지 않은 파일이 없는지 확인하는 것입니다. 일부를 찾으면 새 디렉토리 항목을 작성하여 "lost + found"에 넣습니다.


"정확히하는 다른 프로그램"은 무엇입니까?
phk

@phk 그가 구체적으로 무엇을 생각하는지 모르지만, 오랜 시간이 걸리고 실패하면 불확실한 상태로 남을 수있는 조치를 수행하기에 충분한 일반적인 접근 방식입니다. 예를 들어, 원격 서버에서 다운로드하려고 할 때 서버가 시간 초과 될 가능성이있는 경우 전체 내용을 임시 파일로 다운로드하는 방법이 있습니다. 이렇게하면 다운로드에 문제가 발생해도 원본 파일이 남아 있습니다.
cwallenpoole

내가 아는 유일한 프로그램은 FreeHand입니다. 저장 중에 충돌이 발생하면 원본 파일이 엉망이 아닌 임시 파일이 남아 있기 때문입니다. 그러나 나는 다른 프로그램들도 그것을 보았다. 현재로서는 구체적인 예를 제시 할 수 없습니다.
스네이크

2

사용할 수 있습니다 readlink FILE; echo $?. 하드 링크 인 경우 1을, 심볼릭 링크 인 경우 0을 반환합니다.

맨 페이지에서 : "읽기 링크로 호출 될 때 기호 링크의 대상 만 인쇄됩니다. 주어진 인수가 기호 링크가 아닌 경우 readlink는 아무것도 인쇄하지 않고 오류와 함께 종료됩니다."

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.