Linux Filesystem
파일은 한 덩어리로 한 곳에 있는 게 아니다. 세 부분이 분리돼 서로 연결된 구조다.
- 이름 = 디렉터리에 저장
- 메타데이터 =
inode에 저장 - 실제 데이터 = 디스크 블록에 저장
경로(Path)의 실체
$ /bin/zsh --version
zsh 5.9 (arm64-apple-darwin25.0)
$ /bin/../usr/../bin/./zsh --version
zsh 5.9 (arm64-apple-darwin25.0)- 파일 경로는 고정된 주소가 아니다. 루트(
/)에서 시작해 디렉터리 테이블을 한 단계씩 따라가는 길 안내(route)다. .과..도 각 디렉터리 테이블에 실제로 들어 있는 항목이다(아래ls -ali참고). 그래서/bin/..은/로,/usr/..도/로 돌아가고, 결국 두 경로는 같은 파일에 도착한다.
디렉터리와 테이블
$ ls -ali
total 12
1048577 drwxrwxr-x 2 meatsby meatsby 4096 Oct 3 20:24 .
262145 drwxr-x--- 7 meatsby meatsby 4096 Oct 3 20:23 ..
1048578 -rw-rw-r-- 1 meatsby meatsby 13 Oct 3 20:26 notes.txt
1048579 -rw-rw-r-- 1 meatsby meatsby 0 Oct 3 20:24 photo.png- 디렉터리 = 파일을 담는 상자가 아니라, 파일 이름과
inode번호를 짝지은 테이블을 내용으로 가진 파일이다. ls -i= 각 이름이 가리키는inode번호(맨 앞 컬럼)를 보여준다..= 이 디렉터리 자신의inode(1048577),..= 부모 디렉터리의inode(262145).
아이노드(inode)의 역할
$ stat notes.txt
File: notes.txt
Size: 13 Blocks: 8 IO Block: 4096 regular file
Device: fd01h/64769d Inode: 1048578 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 501/ meatsby) Gid: ( 1000/ meatsby)
Access: 2026-10-03 20:23:57.520195097 +0800
Modify: 2026-10-03 20:26:22.027794491 +0800
Change: 2026-10-03 20:26:22.027794491 +0800
Birth: 2026-10-03 20:23:57.520195097 +0800inode= 파일의 메타데이터를 담는 구조다. 파일 유형, 크기, 소유자, 권한, 시간, 실제 데이터 블록의 위치가 들어 있다.- 파일 이름은
inode에 없다. 이름은 디렉터리 테이블에만 있다. stat= 파일이 가리키는inode의 정보를 보여준다.Links= 이inode를 가리키는 이름의 개수.
하드 링크
$ echo "hi" > a
$ ln a b
$ ls -li
total 8
1048581 -rw-rw-r-- 2 meatsby meatsby 3 Oct 3 20:37 a
1048581 -rw-rw-r-- 2 meatsby meatsby 3 Oct 3 20:37 b- 하드 링크 = 같은
inode를 가리키는 이름을 하나 더 만드는 것이다.a와b는inode번호가 같다. - 원본과 사본의 구분이 없다. 둘 다 같은 자격의 이름이다.
a를 지워도b가 같은inode를 가리키므로hi데이터는 남는다.ls -l의 2번째 컬럼(2) = 링크 수. 링크 수가 0이 되어야 데이터가 실제로 해제된다.
심볼릭 링크
# 심링크 생성
$ ln -s /bin/bash z
$ ls -l z
lrwxrwxrwx 1 meatsby meatsby 9 Oct 3 20:47 z -> /bin/bash
# macOS 의 /tmp 도 심링크다
$ ls -ld /tmp
lrwxr-xr-x@ 1 root wheel 11 Aug 13 10:51 /tmp -> private/tmp
$ cd /tmp
$ pwd
/tmp
$ pwd -P # 심링크를 풀어낸 실제 경로
/private/tmp- 심볼릭 링크(심링크) = 대상의 경로 문자열을 내용으로 가진 별도의 파일이다. 자기만의
inode를 따로 가진다. - 파일 크기가 곧 경로 문자열의 길이다.
/bin/bash는 9바이트,private/tmp는 11바이트. - 경로만 들고 있으므로 대상이 지워지거나 옮겨지면 링크가 깨진다(dangling). 하드 링크와 반대다.
pwd= 셸이 기억하는 논리 경로(심링크 이름 그대로),pwd -P= 심링크를 푼 물리 경로.
작업 디렉터리
$ type cd
cd is a shell builtin- 현재 작업 디렉터리(
pwd) = 커널이 프로세스마다 따로 관리하는 상태다. - 프로세스의 작업 디렉터리는 그 프로세스 자신만 바꿀 수 있다.
- 그래서
cd는 외부 프로그램이 아니라 셸 빌트인이어야 한다.- 셸에서 외부 프로그램을 실행하면 자식 프로세스가 만들어진다. 자식은 부모의 환경을 물려받은 독립된 프로세스다.
cd가 외부 프로그램이면 자식 프로세스의 디렉터리만 바뀌고, 자식이 끝나면 그 변경도 같이 사라진다. 셸은 그대로 원래 자리에 있다.- 셸 프로세스 안에서 직접 실행해야 셸 자신의 상태가 바뀌고, 이후 명령에도 반영된다.
- 같은 이유로 설정 파일은
./file이 아니라source로 읽는다(01. Bash 기초의 source vs 실행 참고).
Swap 설정
Swap 이란?
Swap은 물리 메모리(RAM)가 부족할 때 디스크 공간을 가상 메모리로 사용하는 기술이다. 메모리 부족 시 사용 빈도가 낮은 데이터를 디스크로 이동시켜 메모리 공간을 확보한다.
사용 사례
- 01. Amazon EC2 t3.micro 와 같은 free-tier 인스턴스를 사용할 때 OOM Kill process 가 자주 발생하는 경우
- 물리 메모리가 제한적인 환경에서 시스템 안정성을 높이고자 할 때
Swap 파일 크기 계산
Swap Partition 크기 계산은 AWS 공식 문서를 참고
메모리 확인
free -mSwap 파일 생성
# dd 명령을 통해 root file system 에 swap file 을 생성
# bs(블록 크기) * count(블록 수) = swap file 의 크기
# bs(블록 크기)는 인스턴스에서 사용 가능한 메모리보다 작아야 함
sudo dd if=/dev/zero of=/swapfile bs=128M count=32Swap 파일 권한 설정
# swap file 의 rw 권한 업데이트
sudo chmod 600 /swapfileSwap 영역 설정
# linux swap 영역 설정
sudo mkswap /swapfileSwap 활성화
# swap 공간에 swap file 을 추가해 즉시 사용할 수 있도록 함
sudo swapon /swapfile
# 절차 성공 확인
sudo swapon -s부팅 시 자동 활성화
# swap file 을 활성화할 수 있게 설정
sudo vi /etc/fstab
# 파일 끝에 아래 줄을 추가하고 저장
/swapfile swap swap defaults 0 0설정 확인
# 메모리 재확인 시 swap memory 가 allocate 된 것을 확인 가능
free -m