inode, hard link, symbolic link - 아이노드는 무엇이며, 하드링크와 심볼릭링크의 차이는?

링크를 이해하기 위해서는 inode라는 것을 먼저 알아야 한다.

inode

inode 는 유닉스 계열의 파일시스템에서 사용하는 자료구조로, 파일을 식별하는 번호 및 각종 정보들을 가지고 있어서 파일시스템에 있어서 핵심적인 개념이라고 볼 수 있다.

아이노드는 파일 내용을 저장하고 있는 것이 아니라 파일이 위치한 주소를 가지고 있기 때문에, 사용자가 파일에 접근하려고 할 때 아이노드 번호로 매핑된다.

inode 번호는 데이터가 물리적으로 위치해있는 곳에 접근할 수 있는 정보라고 생각하면 된다.

파일의 inode 번호를 확인하기 위해서는 ls -i를 사용하면 맨 앞부분에 번호가 뜬다.

inode 에는 아이노드 번호, 파일 모드, 링크된 숫자, 소유자, 파일 크기, 수정 내역 등의 정보들이 저장되는데, 이러한 inode 의 정보들을 자세하게 확인하기 위해서는 stat 을 사용할 수 있다.

touch test
stat test
bconfiden2@bconfiden2:~$ stat test
  File: test
  Size: 0         	Blocks: 0          IO Block: 4096   regular empty file
Device: 10302h/66306d	Inode: 26609369    Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/bconfiden2)   Gid: ( 1000/bconfiden2)
Access: 2021-08-27 10:49:15.736576001 +0900
Modify: 2021-08-27 10:49:15.736576001 +0900
Change: 2021-08-27 10:49:15.736576001 +0900
 Birth: -


하드 링크

하드 링크는 유닉스 계열에서 전통적으로 생성하던 링크이다. ln filename linkname의 형태로 하드 링크를 생성할 수 있다.

파일을 만들게 되면, 기본적으로 하나의 하드 링크(자기 자신)가 존재하게 된다. 즉, 파일의 내용이 어딘가에 기록되고 이에 접근할 수 있는 아이노드가 만들어지면서, 우리가 명시했던 파일 이름이 해당 아이노드를 가리키는 첫번째 하드 링크가 되는 것이다.

touch test의 경우는 test가 어떤 아이노드를 가리키는 하드 링크가 되며, test에 대한 하드 링크를 생성할 경우 똑같은 아이노드를 가리키는 하드 링크가 생성된다.

C++에서 레퍼런스를 거는 것과 비슷하다. 하드 링크들은 같은 아이노드를 가리키고 있다.

touch test # 파일이 만들어지고, 아이노드가 만들어지고, test 라는 하드링크가 생성됨
ln test test2 # test 에 대한 하드링크를 생성

ls -i | grep test # test와 test2 의 아이노드가 같은 것을 확인
# 출력
26609369 test
26609369 test2

test의 경로가 바뀌거나 내용을 수정하더라도, test2 역시 같은 아이노드를 통해 파일에 접근하기 때문에 수정된 내용을 확인할 수 있다.

우리가 rm test로 하드 링크를 하나 삭제할 경우에도, test가 가리키고 있던 아이노드에는 test2라는 또다른 하드링크가 붙어있기 때문에 아이노드는 실제로 지워지지 않는다.

즉 test를 삭제해도 test2가 그대로 파일 내용에 접근할 수 있다.


심볼릭 링크

심볼릭 링크는 ln -s item linkname의 형태로 만들 수 있는데, 하드 링크와 다른 점은 디렉토리에도 링크를 걸 수 있다는 것이다.

심볼릭 링크는 참조될 파일이나 디렉토리를 가리키는 포인터가 포함된 파일을 생성한다.

하드 링크는 같은 아이노드를 가리키고 있지만, 심볼릭 링크는 해당 아이노드를 가리키는 또다른 아이노드를 만드는 방식이다.

실제로 아이노드를 비교해보면, 다른 값이 나오는 걸 볼 수 있다. 또한 하드 링크는 일반적인 파일처럼 표시되지만, 심볼릭 링크는 l로 표시된다.

touch test
ln -s test test2 # test 에 대한 심볼릭 링크 생성
ln test test3   # test 에 대한 하드 링크 생성

ls -il | grep test
# 출력 - inode 번호가 다름
26609369 -rw-rw-r--  2 bconfiden2 bconfiden2      24  8월 27 11:45 test
26618326 lrwxrwxrwx  1 bconfiden2 bconfiden2       4  8월 27 12:05 test2 -> test
26609369 -rw-rw-r--  2 bconfiden2 bconfiden2      24  8월 27 11:45 test3

즉 C++에서 레퍼런스가 아닌 포인터를 설정하는 것과 비슷하다.

심볼릭 링크에서 편집을 하면 링크 그 자체에서 실행되는 것이 아니라, 링크가 가리키고 있는 원본 파일에서 이루어지기 때문에, 심볼릭 링크에서 편집을 하더라도 원본 파일에서도 똑같이 변경이 이루어진다.

기존 아이노드를 가리키는 포인터 역할의 새로운 아이노드를 만들기 때문에, 원본 파일을 삭제할 경우 해당 파일에 접근할 수 없게 된다.

링크 그 자체(포인터 역할의 아이노드)는 살아있지만, 해당 링크를 타고 들어간 아이노드가 사라졌기 때문에 링크가 깨졌다고 표현되며, ls 등의 명령어를 실행시켰을 때 깨져있는 링크는 터미널에서 일반적으로 빨간색으로 표시된다.