금일 수업시간에 ../../../ … 무한히 반복되어 root 그 이상의 파일 시스템에 접근(?) 하려했을 때도 여전히 루트 디렉토리를 가리키는 현상을 보았습니다.
- 이는 파일시스템의 근본적인 설계와 관련이 있는데 한번 알아보려고 합니다.
inode
파일시스템에서 모든 파일/디렉토리는 고유한 inode번호를 가집니다.
inode에는 메타데이터(권한, 소유자, 크기, 데이터 블록 위치 등)가 저장되고, 파일명은 디렉토리 엔트리에 저장됩니다.
자세한 inode 구조는 아래의 링크를 참고하면 좋을 거 같습니다.
[UNIX] Inode, 디렉터리
리눅스와 디렉터리 리눅스의 파일 구분 리눅스에서는 파일을 일반 파일과 특수 파일, 디렉터리로 구분 디렉터리는 해당 디렉터리에 속한 파일을 관리하는 특별한 파일 리눅스의 파일 구성 파일
velog.io
디렉토리의 내부 구조
- 디렉토리는 사실
파일명 -> inode 번호매핑 테이블입니다.- 매핑 테이블이라 함은 여러 가지 정보들을 빠르게 조회할 수 있도록 만들어둔 전화번호부라고 생각하면 됩니다.
일반 디렉토리 /home의 내부:
┌─────────────┬─────────────┐
│ 파일명 │ inode 번호 │
├─────────────┼─────────────┤
│ . │ 1234 │ ← 자기 자신
│ .. │ 2 │ ← 부모 (/)
│ user1 │ 5678 │
│ user2 │ 5679 │
└─────────────┴─────────────┘
루트 디렉토리 /의 내부:
┌─────────────┬─────────────┐
│ 파일명 │ inode 번호 │
├─────────────┼─────────────┤
│ . │ 2 │ ← 자기 자신
│ .. │ 2 │ ← 부모도 자기 자신!
│ home │ 1234 │
│ etc │ 3456 │
└─────────────┴─────────────┘
Linux에서도 이를 터미널에서 확인 해볼 수 있습니다.
ls -lai /
l(Long): 파일의 상세 정보(권한, 소유자, 크기, 수정 날짜 등)를 리스트 형식으로 보여줍니다.a(All): 마침표(.)로 시작하는 숨겨진 파일과 디렉토리(.,..)까지 모두 보여줍니다.i(Inode): 파일이나 디렉토리 왼쪽에 해당 항목의 inode 번호를 표시합니다.
root에서의 inode 매핑 테이블 확인

- 자기 자신을 가리키는
., 부모를 가리키는..모두 inode 2번입니다.
root가 아닌 디렉토리에서 inode 매핑 테이블 확인

- 자기 자신을 가리키는 inode는 134, 부모 inode는 128(root)인 것을 확인할 수 있다.
왜 이럼?
여기서부턴 제 생각입니다..
- 파일시스템은 트리 구조입니다.
- 수업시간
네트워크 토폴로지에서도 나왔듯, 모든 트리 구조에는 루트가 존재합니다. - 루트의 부모는 정의상 존재하지 않습니다.
- 수업시간
- 만약 이런 상황을 예외처리했다면?
..를 없애거나 에러를 발생시켰을 때 모든 프로그램에 대해루트예외처리를 추가해야했습니다.- 루트의 inode 매핑 테이블에서 부모를 자신으로 가리키게 함으로써 이러한 예외처리가 불필요해졌고, inode 구조의 일관성을 유지할 수 있었습니다.
- 추가적으로 경로 해석(Pathname Resolution)의 단순화를 이끌어낼 수 있었습니다.
ls의 동작 방식
단순히 ls를 해서 존재하는 파일들이 나오네!가 아닌 동작 원리를 봅니다.
[리눅스] 디렉토리 읽기 구현 - 재귀적으로 하위 디렉토리 호출(lstat)
[리눅스] 디렉토리 읽기 구현 - 재귀적으로 하위 디렉토리 호출(lstat)
디렉토리, 파일과 관련한 더 많은 정보와 예제 코드 를 담은 리눅스 교재를 배포했습니다. 아래의 페이지에서 리눅스 교재를 받아가세요. https://reakwon.tistory.com/233 리눅스 프로그래밍 note 배포 티
reakwon.tistory.com
ls가 마법을 부려서 지정된 디렉토리의 파일 및 하위 디렉토리 목록을 보여주는 건 아닙니다.
- 내부적으로는 여러 시스템 콜(syscall)을 호출하여 파일 시스템에 직접 접근해 파일 정보를 읽어오고, 옵션에 따라 정렬 및 포맷팅하여 사용자에게 보여줍니다.
즉, 리눅스 시스템 내에서 알아서 정보를 취합해 우리에게 보여주는 것인데요, 핵심 동작 원리는 아래와 같습니다.
1. opendir("/")로 디렉토리 열기
2. readdir()로 엔트리 순회
-> readdir은 파일의 이름과 inode 번호만 담긴 dirent 구조체를 반환하며,
-> 이 단계에서는 아직 상세 정보(권한, 크기 등)를 모릅니다
// 옵션들
3. -l 옵션 시: stat()으로 inode 메타데이터 조회
-> readdir()로 얻은 inode 번호를 바탕으로
-> 각 파일마다 개별적으로 stat()을 호출
-> inode의 상세 메타데이터를 조회
4. -i 옵션 시: inode 번호 출력
5. -a 옵션 시: . 과 .. 도 출력
- 실제로 위의 첨부된 블로그 글을 통해 ls의 내부 구현을 확인할 수도 있습니다.
중요한 부분은 트리 구조의 파일 시스템을 읽기 위해 재귀적으로 엔트리를 순회한다는 점인 것 같습니다.
정리
결국 cd ../../../를 무한히 해도 루트에 머무는 이유는 "파일 시스템 트리의 최상단 노드가 자기 자신을 부모로 가리키도록 링크"되어 있기 때문입니다.
- 이는 OS가 경로를 탐색할 때 예외 상황 없이 동일한 로직을 수행할 수 있게 만듭니다.
[추가적으로 알아볼만한 내용]
- Hard Link vs Symbolic Link
- Unlink
'Infra > Linux' 카테고리의 다른 글
| 어떻게 /etc/passwd와 같은 파일을 r,w 할까? (0) | 2026.01.09 |
|---|