리눅스 lsof 완벽 가이드 - 포트 충돌부터 삭제된 파일 용량 확보까지 실무 핵심 팁

개요

리눅스 시스템 운영 중 발생하는 ‘포트 충돌’이나 ‘삭제해도 줄어들지 않는 디스크 용량’ 문제는 lsof 명령어로 즉시 해결할 수 있습니다. 이 글에서는 모든 것을 파일로 관리하는 리눅스 환경에서 lsof를 실무에 바로 적용하는 핵심 기법을 살펴봅니다. 포트 추적부터 파일 락 해제까지 시스템 엔지니어의 필수 트러블슈팅 노하우를 단계별로 알아봅니다.

lsof 기본 점검 및 특정 사용자/프로세스의 열린 파일 확인

시스템에 lsof 명령어가 설치되어 있는지 확인하고, 설치되어 있지 않은 경우 패키지를 설치하기 위해 command -v lsof >/dev/null 2>&1 || (apt-get update -qq && apt-get install -y lsof) 명령어를 실행합니다.

command -v lsof >/dev/null 2>&1 || (apt-get update -qq && apt-get install -y lsof)

lsof 명령어의 설치 버전과 빌드 정보를 확인하기 위해 lsof -v 명령어를 실행합니다.
⚙️ [주요 옵션]

-u : 특정 사용자 계정이 열고 있는 파일 및 프로세스 목록을 조회합니다.
-c : 지정한 프로세스 이름으로 시작하는 프로세스가 연 파일 목록을 필터링합니다.
-p : 특정 프로세스 ID(PID)가 열고 있는 파일 목록을 확인합니다.
-i : 네트워크 소켓 및 특정 포트를 사용하는 프로세스를 조회합니다.
+D : 지정한 디렉터리 및 하위 경로에서 열려 있는 파일 목록을 재귀적으로 검색합니다.
-t : 프로세스 ID(PID)만 간결하게 한 줄씩 출력하여 스크립트 연동에 유용합니다.

lsof -v

lsof 실습을 위한 테스트 디렉터리와 샘플 파일을 준비하기 위해 mkdir -p /tmp/lsof_lab && echo '테스트 파일 내용' > /tmp/lsof_lab/sample.txt 명령어를 실행합니다.

mkdir -p /tmp/lsof_lab && echo ‘테스트 파일 내용’ > /tmp/lsof_lab/sample.txt

생성한 샘플 파일을 프로세스가 계속 열고 있도록 백그라운드에서 추적하기 위해 tail -f /tmp/lsof_lab/sample.txt & 명령어를 실행합니다.

tail -f /tmp/lsof_lab/sample.txt &

lsof -u $(whoami) | head -n 15 명령어는 현재 로그인한 사용자가 실행 중인 프로세스들이 점유하고 있는 파일 목록을 상위 15줄까지 조회합니다.
기본적인 시스템 라이브러리와 실행 파일 등 현재 계정이 열고 있는 파일들의 세부 정보를 확인할 수 있습니다.

lsof -u $(whoami) | head -n 15

lsof -c tail 명령어는 프로세스 이름이 tail인 프로세스가 열고 있는 파일과 라이브러리 목록을 검색하여 출력합니다.
이를 통해 백그라운드에서 실행한 tail 명령어가 어떤 파일 디스크립터와 공유 라이브러리를 참조하고 있는지 확인할 수 있습니다.

lsof -c tail

실습을 마친 후 백그라운드에서 실행 중이던 tail 프로세스를 안전하게 종료하고 정리하기 위해 killall tail 2>/dev/null || true 명령어를 실행합니다.

killall tail 2>/dev/null || true

네트워크 포트 점검 및 프로세스 충돌 트러블슈팅

포트 점검 및 프로세스 충돌 실습 환경을 마련하기 위해 시스템에 python3가 설치되어 있는지 확인하고 미설치 시 패키지를 설치합니다.

command -v python3 >/dev/null 2>&1 || (apt-get update -qq && apt-get install -y python3)

네트워크 포트 점유 테스트를 위해 8080번 포트로 간단한 웹 서버를 백그라운드에서 구동합니다.

python3 -m http.server 8080 >/dev/null 2>&1 &

백그라운드로 구동한 웹 서버 프로세스가 8080번 포트에 정상적으로 바인딩될 때까지 1초간 대기합니다.

sleep 1

lsof -i :8080 명령어는 8080번 포트를 사용 중인 프로세스를 조회합니다.
출력 결과를 통해 PID 371번의 python3 프로세스가 8080번 포트에서 LISTEN 상태로 대기 중임을 확인할 수 있습니다.

lsof -i :8080

lsof -i -P -n | head -n 15 명령어는 시스템의 네트워크 소켓 목록을 포트 번호와 IP 주소 변환 없이 숫자로 빠르게 출력합니다.
DNS 역조회나 서비스 포트 이름 매핑 과정을 생략하므로 지연 없이 빠르게 포트 점유 현황을 파악할 수 있습니다.

lsof -i -P -n | head -n 15

lsof -i TCP:8080 -sTCP:LISTEN 명령어는 8080번 포트 중에서도 TCP 프로토콜과 LISTEN 상태에 있는 연결만 정밀하게 필터링하여 출력합니다.
불필요한 세션 연결을 제외하고 실제로 해당 포트에서 접속 대기 중인 데몬 프로세스만 정확히 식별할 때 유용합니다.

lsof -i TCP:8080 -sTCP:LISTEN

실습을 마친 후 8080번 TCP 포트를 점유하고 있던 백그라운드 웹 서버 프로세스를 강제 종료하여 점유 자원을 정리합니다.

fuser -k 8080/tcp 2>/dev/null || kill $(lsof -t -i :8080) 2>/dev/null || true

특정 디렉터리 및 마운트 해제 방해 파일(Device Busy) 추적

디렉터리 점유 및 마운트 해제 방해 상황을 재현하기 위해 실습용 디렉터리를 생성하고 해당 경로로 이동합니다.

mkdir -p /tmp/mount_test && cd /tmp/mount_test

프로세스가 열람할 대상 로그 파일을 생성하기 위해 echo '작업 중인 파일' > active_work.log 명령어를 실행합니다.

echo ‘작업 중인 파일’ > active_work.log

생성한 파일을 표준 입력으로 참조하여 지속적으로 점유하도록 백그라운드에서 sleep 프로세스를 실행합니다.

sleep 30 < active_work.log &

점유 중인 디렉터리 외부에서 상태를 점검하기 위해 홈 디렉터리로 작업 경로를 변경합니다.

cd /root || cd ~

lsof +D /tmp/mount_test 명령어는 지정한 디렉터리와 그 하위 경로에서 열려 있는 모든 파일 및 프로세스를 재귀적으로 추적하여 출력합니다.
출력 결과를 통해 PID 450번의 sleep 프로세스가 해당 디렉터리를 현재 작업 디렉터리(cwd)로 참조하고, active_work.log 파일을 읽기 모드(0r)로 열고 있어 마운트 해제를 방해하는 원인임을 확인할 수 있습니다.

lsof +D /tmp/mount_test

실습을 마친 후 디렉터리와 파일을 점유하고 있던 백그라운드 sleep 프로세스를 안전하게 종료합니다.

killall sleep 2>/dev/null || true

실습에 사용했던 임시 테스트 디렉터리와 하위 파일을 모두 삭제하여 시스템 자원을 정리합니다.

rm -rf /tmp/mount_test

삭제되었지만 디스크를 점유 중인 유령 파일(deleted) 복구 및 정리

디스크 용량 누수 테스트를 위해 실습용 디렉터리를 생성하고 10MB 크기의 대용량 테스트 파일을 생성합니다.

mkdir -p /tmp/leak_test && dd if=/dev/zero of=/tmp/leak_test/large.img bs=1M count=10 >/dev/null 2>&1

생성한 대용량 파일의 핸들을 프로세스가 계속 유지하도록 백그라운드에서 추적합니다.

tail -f /tmp/leak_test/large.img &

점유 중인 대용량 파일을 파일 시스템 상에서 강제로 삭제하여 유령 파일 누수 상황을 재현합니다.

rm -f /tmp/leak_test/large.img

lsof | grep '(deleted)' | head -n 5' 명령어는 파일 시스템에서 삭제되었지만 프로세스가 여전히 열고 있어 디스크 용량을 점유 중인 파일 목록을 조회합니다.
이를 통해 rm 명령어로 삭제했음에도 디스크 공간이 반환되지 않는 유령 파일과 해당 프로세스를 신속하게 추적할 수 있습니다.

lsof | grep ‘(deleted)’ | head -n 5

lsof -t로 추출한 프로세스 ID를 바탕으로 /proc/$TARGET_PID/fd/ 디렉터리의 파일 디스크립터 목록을 조회합니다.
프로세스가 참조 중인 파일 디스크립터 번호를 직접 확인함으로써, 프로세스를 재시작하지 않고도 용량을 비우거나 필요한 경우 해당 디스크립터를 통해 삭제된 원본 데이터를 복구할 수 있습니다.

TARGET_PID=$(lsof -t /tmp/leak_test/large.img 2>/dev/null | head -n 1) && [ -n “$TARGET_PID” ] && ls -l /proc/$TARGET_PID/fd/ || true

실습을 마친 후 유령 파일을 계속 점유하고 있던 백그라운드 프로세스를 안전하게 종료하여 디스크 용량을 완전히 반환합니다.

killall tail 2>/dev/null || true

실습에 사용했던 임시 테스트 디렉터리를 완전히 삭제하여 시스템 자원을 정리합니다.

rm -rf /tmp/leak_test

지금까지 lsof 명령어를 활용해 포트 충돌 해결부터 삭제된 파일의 디스크 용량 확보까지 실무 핵심 팁을 간단하게 살펴보았습니다.
이번에 정리한 내용이 실제 서버 운영과 트러블슈팅 상황에서 문제 해결에 많은 도움이 되기를 바랍니다.