GNU/Linux에서 하드 링크를 삭제하는 방법 및 inode 이야기
안녕하세요, 무능입니다.
오랜만에 ln 명령어로 링크를 생성하려고 했을 때 실수로 -s 옵션을 지우는 것을 잊어버려서 하드 링크가 생성되어 버렸습니다. 그래서 불필요한 하드 링크를 삭제하려고 합니다.
하드 링크 생성하기
옵션 없이 ln 명령어를 실행하면 하드 링크가 생성됩니다.
alleycat:[haturatu]:~/git/hardlink$ ls
alleycat:[haturatu]:~/git/hardlink$ touch hardlink1
alleycat:[haturatu]:~/git/hardlink$ echo "You are an idiot" >> hardlink1
alleycat:[haturatu]:~/git/hardlink$ cat hardlink1
You are an idiot
alleycat:[haturatu]:~/git/hardlink$ ls -la
합계 12
drwxr-xr-x 2 haturatu haturatu 4096 1월 12 15:00 .
drwxr-xr-x 114 haturatu haturatu 4096 1월 12 15:00 ..
-rw-r--r-- 1 haturatu haturatu 17 1월 12 15:01 hardlink1
위와 같이 파일을 생성해 보았습니다.
alleycat:[haturatu]:~/git/hardlink$ ln hardlink1 hardlink2
alleycat:[haturatu]:~/git/hardlink$ ls -la
합계 16
drwxr-xr-x 2 haturatu haturatu 4096 1월 12 15:02 .
drwxr-xr-x 114 haturatu haturatu 4096 1월 12 15:00 ..
-rw-r--r-- 2 haturatu haturatu 17 1월 12 15:01 hardlink1
-rw-r--r-- 2 haturatu haturatu 17 1월 12 15:01 hardlink2
이렇게 하드 링크가 생성되었습니다.
그리고 다음 표준 출력을 살펴보겠습니다.
-rw-r--r-- 2 haturatu haturatu 17 1월 12 15:01 hardlink1
-rw-r--r-- 2 haturatu haturatu 17 1월 12 15:01 hardlink2
이 -rw-r--r-- 2의 2는 하드 링크된 개수입니다. 하드 링크되기 전과 비교하여 값이 증가한 것을 확인할 수 있을 것입니다.
그리고 이것은 단순히 링크된 것이므로 디스크 용량 자체를 압박하지 않습니다. 단일 데이터를 저장하며, inode 번호는 동일하여 같은 파일을 가리킵니다.-i 옵션으로 inode 번호를 확인합니다.
alleycat:[haturatu]:~/git/hardlink$ ls -lia
합계 16
13238408 drwxr-xr-x 2 haturatu haturatu 4096 1월 12 15:02 .
11406555 drwxr-xr-x 114 haturatu haturatu 4096 1월 12 15:00 ..
13265123 -rw-r--r-- 2 haturatu haturatu 17 1월 12 15:01 hardlink1
13265123 -rw-r--r-- 2 haturatu haturatu 17 1월 12 15:01 hardlink2
inode란?
이것은 파일 시스템에 의존하므로 위 내용은 GNU/Linux 환경이며 BSD 계열 파일 시스템에서는 vnode, ZFS에서는 znode 등으로 약간 다르지만 역사적으로 보면 원래 UNIX 파일 시스템을 확장한 것이라고 이해하면 될 것 같습니다.
그리고 심볼릭 링크와 달리 하드 링크는 hardlink1을 지워도 hardlink2는 남고, hardlink2를 지워도 hardlink1은 남습니다. 이 점으로 미루어 볼 때 파일 시스템이 해당 파일 자체를 관리하기 때문이라고 설명할 수 있겠지만, 여전히 다소 난해합니다.
하지만 이렇게 보면 하드 링크는 편리하지만 심볼릭 링크는 다른 디스크의 파일도 참조할 수 있는 반면 하드 링크의 경우 다른 디스크에는 생성할 수 없습니다.
앞서 설명한 내용을 바탕으로 간단히 말하면, 파일 시스템은 단일 디스크의 inode를 기준으로 하므로 다른 디스크의 경우 해당 파일 시스템의 관할 범위를 벗어나 계층 구조적으로 참조할 수 없습니다.
따라서 다른 디스크에 존재하는 경우 심볼릭 링크를 생성할 필요가 있습니다.
그리고 파일 시스템 관점에서 이를 일상적으로 사용하는 경우는 디스크 복구, 복원 작업 시 과거 inode 정보를 참조하여 어떤 inode 번호의 파일이 생성되었는지, 삭제되었는지 식별하는 것입니다.
여기서 함정은 파일이 덮어쓰기되면 이 inode 번호도 업데이트된다는 것입니다. 즉, 백업 스크립트 등을 만들 때는 덮어쓰기 처리가 발생하지 않도록 스크립트를 작성하는 의식이 필요할 수 있습니다. (저는 한 번 실수했습니다)
동일한 inode 번호의 파일 식별하기
find 명령어로 확인할 수 있습니다.
alleycat:[haturatu]:~/git/hardlink$ find . -inum 13265123
./hardlink2
./hardlink1
자, 이제 hardlink1을 삭제해 보겠습니다.
alleycat:[haturatu]:~/git/hardlink$ rm -i hardlink1
rm: 일반 파일 'hardlink1'을 삭제하시겠습니까? y
alleycat:[haturatu]:~/git/hardlink$ ls -lai
합계 12
13238408 drwxr-xr-x 2 haturatu haturatu 4096 1월 12 15:23 .
11406555 drwxr-xr-x 114 haturatu haturatu 4096 1월 12 15:00 ..
13265123 -rw-r--r-- 1 haturatu haturatu 17 1월 12 15:01 hardlink2
alleycat:[haturatu]:~/git/hardlink$ cat hardlink2
You are an idiot
이렇게 하드 링크된 값도 1이 되었고, 원래 ln hardlink1 hardlink2로 hardlink1의 링크를 생성하여, hardlink1과 동일한 정보를 가진 hardlink2가 존재하며 같은 데이터를 가지고 있음을 확인할 수 있었습니다.
활용 측면에서
오랜만에 다뤄봤지만, 동일한 디스크 내에서 큰 파일을 복사하고 싶지만 디스크 소모를 줄이고 싶다면 하드 링크를 사용하는 것이 좋을 것 같습니다.
음, 그렇게 의식적으로 사용할 만한 것은 아닐 수도 있지만 파일 시스템의 구조를 조금 이해할 수 있게 해주는 것이라 흥미로운 것 같습니다.
그럼 다음에 또 뵙겠습니다.
잘 부탁드립니다.