Miscellaneous

lsof 명령어 (list open files)

강철지그·2016년 12월 27일·조회 9,455

1. 개요

얼마 전 파일 디스크립터에 대해 설명한 적이 있다.

/index.php/miscellaneous/693

오늘은 관련 명령어인 lsof를 간단히 소개하고자 한다. lsoflist open files라는 뜻으로, 흔히 [엘에스오브]라고 발음하는 것 같다. 외국에서는 어떻게 발음하는지 아시는 분 있으면 제보 좀…

리눅스/유닉스 계열에서는 일반 파일뿐 아니라 디렉터리, 라이브러리, 파이프, 소켓까지 “열린 파일”로 취급된다. 그래서 lsof는 단순히 어떤 파일을 누가 쓰는지 확인하는 용도뿐 아니라, 특정 포트를 점유한 프로세스나 파일 디스크립터 사용량을 확인할 때도 유용하다.


2. 설치

우선 yum을 이용하여 설치해 보도록 하자.

# yum install lsof
Loaded plugins: fastestmirror
Determining fastest mirrors
 * base: ftp.daumkakao.com
 * extras: ftp.daumkakao.com
 * updates: ftp.daumkakao.com
base                                                                                                       | 3.7 kB     00:00
extras                                                                                                     | 3.4 kB     00:00
extras/primary_db                                                                                          |  37 kB     00:00
updates                                                                                                    | 3.4 kB     00:00
updates/primary_db                                                                                         | 2.6 MB     00:00
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package lsof.x86_64 0:4.82-5.el6 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

==================================================================================================================================
 Package                     Arch                          Version                              Repository                   Size
==================================================================================================================================
Installing:
 lsof                        x86_64                        4.82-5.el6                           base                        324 k

Transaction Summary
==================================================================================================================================
Install       1 Package(s)

Total download size: 324 k
Installed size: 900 k
Is this ok [y/N]: y
Downloading Packages:
lsof-4.82-5.el6.x86_64.rpm                                                                                 | 324 kB     00:00
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing : lsof-4.82-5.el6.x86_64                                                                                         1/1
  Verifying  : lsof-4.82-5.el6.x86_64                                                                                         1/1

Installed:
  lsof.x86_64 0:4.82-5.el6

Complete!

배포판에 따라 패키지 관리자는 다를 수 있다. 예를 들어 Debian/Ubuntu 계열에서는 보통 apt로 설치한다.

# apt install lsof

3. 실행

그럼 설치된 lsof를 실행해 보자.

# lsof
COMMAND     PID    USER   FD      TYPE             DEVICE  SIZE/OFF       NODE NAME
init          1    root  cwd       DIR              253,1      4096          2 /
init          1    root  rtd       DIR              253,1      4096          2 /
init          1    root  txt       REG              253,1    150352     917532 /sbin/init
init          1    root  mem       REG              253,1     65928     393290 /lib64/libnss_files-2.12.so
init          1    root  mem       REG              253,1   1921176     393227 /lib64/libc-2.12.so
init          1    root  DEL       REG              253,1               393560 /lib64/libgcc_s-4.4.7-20120601.so.1;5761fb6c
init          1    root  mem       REG              253,1     43880     393562 /lib64/librt-2.12.so
init          1    root  mem       REG              253,1    142640     393251 /lib64/libpthread-2.12.so
init          1    root  mem       REG              253,1    265728     393311 /lib64/libdbus-1.so.3.4.0
init          1    root  mem       REG              253,1     39896     393431 /lib64/libnih-dbus.so.1.0.0
init          1    root  mem       REG              253,1    101920     393433 /lib64/libnih.so.1.0.0
init          1    root  mem       REG              253,1    154624     393306 /lib64/ld-2.12.so
init          1    root    0u      CHR                1,3       0t0       3643 /dev/null
init          1    root    1u      CHR                1,3       0t0       3643 /dev/null
init          1    root    2u      CHR                1,3       0t0       3643 /dev/null
init          1    root    3r     FIFO                0,8       0t0       6488 pipe
init          1    root    4w     FIFO                0,8       0t0       6488 pipe
init          1    root    5r      DIR               0,10         0          1 inotify
init          1    root    6r      DIR               0,10         0          1 inotify
init          1    root    7u     unix 0xffff880037999680       0t0       6489 @/com/ubuntu/upstart
init          1    root    8u     unix 0xffff880037fe0380       0t0     424583 socket
init          1    root    9u     unix 0xffff88007c86a980       0t0       7715 socket

옵션 없이 실행하면 시스템에서 열려 있는 파일 목록이 많이 출력된다. 권한이 부족하면 일부 항목이 보이지 않을 수 있으므로, 운영 상황을 확인할 때는 필요에 따라 root 권한으로 실행한다.


4. 해독

4-1. 주요 컬럼

  • COMMAND: 파일을 열고 있는 명령 또는 프로세스 이름
  • PID: 프로세스 ID
  • USER: 프로세스를 실행한 사용자
  • FD: 파일 디스크립터 정보
  • TYPE: 파일의 종류
  • DEVICE, SIZE/OFF, NODE, NAME: 장치 번호, 크기/오프셋, inode, 파일 또는 소켓 이름

4-2. FD의 의미는 다음과 같다

  • cwd: 현재 디렉터리
  • rtd: 루트 디렉터리
  • txt: 실행 중인 프로그램의 텍스트 파일
  • mem: 메모리 매핑된 파일
  • mmap: 메모리 매핑된 장치
  • NUMBER: 파일 디스크립터 번호. 숫자 뒤의 r은 read, w는 write, u는 read/write를 의미한다.

4-3. TYPE의 의미는 다음과 같다

  • REG: 일반 파일
  • DIR: 디렉터리
  • FIFO: 선입선출 파이프
  • CHR: 캐릭터 특수 파일
  • IPv4, IPv6: 네트워크 소켓
  • unix: 유닉스 도메인 소켓

5. 명령어

특정 프로세스가 사용 중인 파일 디스크립터 수를 간단히 세고 싶다면 다음처럼 확인할 수 있다.

$ lsof -p 프로세스ID | wc -l
  • 해당 프로세스가 사용하고 있는 열린 파일 목록의 줄 수를 센다.
  • 헤더 한 줄도 포함되므로, 정확히 FD 개수만 계산하려면 그 점을 감안해야 한다.
  • 이 값은 일반적으로 ulimit -a에서 확인할 수 있는 open files 제한값의 영향을 받는다.
  • 프로세스가 제한값에 근접할 정도로 파일 디스크립터를 많이 사용하면 새 파일이나 소켓을 열지 못해 장애나 성능 저하의 원인이 될 수 있다.

현재 셸에 적용된 open files 제한은 다음과 같이 확인할 수 있다.

$ ulimit -n

6. 실전

6-1. 특정 파일을 사용하는 프로세스 찾기

이번에는 특정 파일을 찾아보자. /usr/sbin/apache2를 찾는 예이다.

# lsof /usr/sbin/apache2
COMMAND   PID     USER  FD   TYPE DEVICE SIZE/OFF   NODE NAME
apache2  9651     root txt    REG  253,1   474776 921962 /usr/sbin/../lib/apache2/mpm-worker/apache2
apache2 14428 www-data txt    REG  253,1   474776 921962 /usr/sbin/../lib/apache2/mpm-worker/apache2
apache2 14429 www-data txt    REG  253,1   474776 921962 /usr/sbin/../lib/apache2/mpm-worker/apache2
apache2 14430 www-data txt    REG  253,1   474776 921962 /usr/sbin/../lib/apache2/mpm-worker/apache2

6-2. 특정 디렉터리 하위 파일 찾기

이번에는 특정 디렉터리 하위 파일을 찾는 것이다.

# lsof +D /usr/sbin
COMMAND    PID   USER  FD   TYPE DEVICE SIZE/OFF   NODE NAME
rsyslogd   414 syslog txt    REG  253,1   384440 654108 /usr/sbin/rsyslogd
sshd       612   root txt    REG  253,1   517112 659298 /usr/sbin/sshd
vsftpd     634   root txt    REG  253,1   159880 653691 /usr/sbin/vsftpd
acpid      836   root txt    REG  253,1    43792 666185 /usr/sbin/acpid
atd        837 daemon txt    REG  253,1    23152 665363 /usr/sbin/atd
cron       838   root txt    REG  253,1    44320 657705 /usr/sbin/cron
ntpd      1148    ntp txt    REG  253,1   671176 658483 /usr/sbin/ntpd
sshd     16409   root txt    REG  253,1   517112 659298 /usr/sbin/sshd
sshd     17254   root txt    REG  253,1   517112 659298 /usr/sbin/sshd
sshd     17255   sshd txt    REG  253,1   517112 659298 /usr/sbin/sshd

+D는 하위 디렉터리까지 훑기 때문에 대상 경로가 크면 시간이 오래 걸릴 수 있다. 범위를 좁힐 수 있다면 특정 파일이나 더 작은 디렉터리를 지정하는 편이 좋다.

6-3. 특정 프로세스 이름으로 찾기

이번에는 특정 프로세스명으로 검색해 보자.

# lsof -c apache2
COMMAND   PID     USER   FD   TYPE             DEVICE SIZE/OFF     NODE NAME
apache2  9651     root  cwd    DIR              253,1     4096        2 /
apache2  9651     root  rtd    DIR              253,1     4096        2 /
apache2  9651     root  txt    REG              253,1   474776   921962 /usr/lib/apache2/mpm-worker/apache2
apache2  9651     root  mem    REG              253,1   105288   391710 /lib/x86_64-linux-gnu/libresolv-2.15.so
apache2  9651     root  mem    REG              253,1    31104   391718 /lib/x86_64-linux-gnu/libnss_dns-2.15.so
apache2  9651     root  mem    REG              253,1    52120   391721 /lib/x86_64-linux-gnu/libnss_files-2.15.so
apache2  9651     root  mem    REG              253,1    47680   391720 /lib/x86_64-linux-gnu/libnss_nis-2.15.so
apache2  9651     root  mem    REG              253,1    97248   391707 /lib/x86_64-linux-gnu/libnsl-2.15.so
apache2  9651     root  mem    REG              253,1    35680   391722 /lib/x86_64-linux-gnu/libnss_compat-2.15.so

이 옵션은 아래와 같이 중복 사용이 가능하다.

# lsof -c apache2 -c ssh
(생략)
sshd      612     root  mem    REG              253,1   149280   391714 /lib/x86_64-linux-gnu/ld-2.15.so
sshd      612     root    0u   CHR                1,3      0t0     4856 /dev/null
sshd      612     root    1u   CHR                1,3      0t0     4856 /dev/null
sshd      612     root    2u   CHR                1,3      0t0     4856 /dev/null
sshd      612     root    3u  IPv6               7783      0t0      TCP *:ssh (LISTEN)
sshd      612     root    4u  IPv4               7788      0t0      TCP *:ssh (LISTEN)
sshd      612     root    6r  FIFO                0,8      0t0 98449668 pipe
apache2  9651     root  cwd    DIR              253,1     4096        2 /
apache2  9651     root  rtd    DIR              253,1     4096        2 /
apache2  9651     root  txt    REG              253,1   474776   921962 /usr/lib/apache2/mpm-worker/apache2
apache2  9651     root  mem    REG              253,1   105288   391710 /lib/x86_64-linux-gnu/libresolv-2.15.so
apache2  9651     root  mem    REG              253,1    31104   391718 /lib/x86_64-linux-gnu/libnss_dns-2.15.so
apache2  9651     root  mem    REG              253,1    52120   391721 /lib/x86_64-linux-gnu/libnss_files-2.15.so
apache2  9651     root  mem    REG              253,1    47680   391720 /lib/x86_64-linux-gnu/libnss_nis-2.15.so
apache2  9651     root  mem    REG              253,1    97248   391707 /lib/x86_64-linux-gnu/libnsl-2.15.so
(생략)

6-4. 특정 사용자로 찾기

특정 사용자로도 검색할 수 있다.

# lsof -u www-data
COMMAND   PID     USER   FD   TYPE             DEVICE SIZE/OFF     NODE NAME
apache2 14428 www-data  cwd    DIR              253,1     4096        2 /
apache2 14428 www-data  rtd    DIR              253,1     4096        2 /
apache2 14428 www-data  txt    REG              253,1   474776   921962 /usr/lib/apache2/mpm-worker/apache2
apache2 14428 www-data  mem    REG              253,1   105288   391710 /lib/x86_64-linux-gnu/libresolv-2.15.so
apache2 14428 www-data  mem    REG              253,1    31104   391718 /lib/x86_64-linux-gnu/libnss_dns-2.15.so
apache2 14428 www-data  mem    REG              253,1    52120   391721 /lib/x86_64-linux-gnu/libnss_files-2.15.so
apache2 14428 www-data  mem    REG              253,1    47680   391720 /lib/x86_64-linux-gnu/libnss_nis-2.15.so
apache2 14428 www-data  mem    REG              253,1    97248   391707 /lib/x86_64-linux-gnu/libnsl-2.15.so
apache2 14428 www-data  mem    REG              253,1    35680   391722 /lib/x86_64-linux-gnu/libnss_compat-2.15.so
apache2 14428 www-data  mem    REG              253,1    22528   921141 /usr/lib/apache2/modules/mod_status.so
apache2 14428 www-data  mem    REG              253,1    14336   921077 /usr/lib/apache2/modules/mod_setenvif.so
apache2 14428 www-data  mem    REG              253,1    14344   921122 /usr/lib/apache2/modules/mod_reqtimeout.so
apache2 14428 www-data  mem    REG              253,1    34824   921123 /usr/lib/apache2/modules/mod_negotiation.so
apache2 14428 www-data  mem    REG              253,1    18432   921940 /usr/lib/apache2/modules/mod_mime.so
apache2 14428 www-data  mem    REG              253,1    10240   921140 /usr/lib/apache2/modules/mod_env.so
apache2 14428 www-data  mem    REG              253,1    10240   921121 /usr/lib/apache2/modules/mod_dir.so

참고로 lsof -u ^www-data로 실행하면 www-data 사용자만 제외하고 결과를 보여준다. 즉 exclude 조건이다.

6-5. PID로 찾기

이번에는 PID로 검색해 보자.

# lsof -p 9651
COMMAND  PID USER   FD   TYPE   DEVICE SIZE/OFF     NODE NAME
apache2 9651 root  cwd    DIR    253,1     4096        2 /
apache2 9651 root  rtd    DIR    253,1     4096        2 /
apache2 9651 root  txt    REG    253,1   474776   921962 /usr/lib/apache2/mpm-worker/apache2
apache2 9651 root  mem    REG    253,1   105288   391710 /lib/x86_64-linux-gnu/libresolv-2.15.so
apache2 9651 root  mem    REG    253,1    31104   391718 /lib/x86_64-linux-gnu/libnss_dns-2.15.so
apache2 9651 root  mem    REG    253,1    52120   391721 /lib/x86_64-linux-gnu/libnss_files-2.15.so
apache2 9651 root  mem    REG    253,1    47680   391720 /lib/x86_64-linux-gnu/libnss_nis-2.15.so
apache2 9651 root  mem    REG    253,1    97248   391707 /lib/x86_64-linux-gnu/libnsl-2.15.so
apache2 9651 root  mem    REG    253,1    35680   391722 /lib/x86_64-linux-gnu/libnss_compat-2.15.so
apache2 9651 root  mem    REG    253,1    22528   921141 /usr/lib/apache2/modules/mod_status.so
apache2 9651 root  mem    REG    253,1    14336   921077 /usr/lib/apache2/modules/mod_setenvif.so
apache2 9651 root  mem    REG    253,1    14344   921122 /usr/lib/apache2/modules/mod_reqtimeout.so
apache2 9651 root  mem    REG    253,1    34824   921123 /usr/lib/apache2/modules/mod_negotiation.so
apache2 9651 root  mem    REG    253,1    18432   921940 /usr/lib/apache2/modules/mod_mime.so
apache2 9651 root  mem    REG    253,1    10240   921140 /usr/lib/apache2/modules/mod_env.so
apache2 9651 root  mem    REG    253,1    10240   921121 /usr/lib/apache2/modules/mod_dir.so
apache2 9651 root  mem    REG    253,1    92720   391908 /lib/x86_64-linux-gnu/libz.so.1.2.3.4

6-6. 특정 포트를 열고 있는 프로세스 찾기

마지막으로 특정 포트를 열고 있는 프로세스를 찾아보자.

# lsof -i :80
COMMAND   PID     USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
apache2  9651     root    3u  IPv4 55344500      0t0  TCP *:http (LISTEN)
apache2 14429 www-data    3u  IPv4 55344500      0t0  TCP *:http (LISTEN)
apache2 14430 www-data    3u  IPv4 55344500      0t0  TCP *:http (LISTEN)

LISTEN 상태의 TCP 포트만 보고 싶다면 다음처럼 조건을 조금 더 좁힐 수 있다.

# lsof -iTCP -sTCP:LISTEN

댓글 0

로그인 후 댓글을 남길 수 있습니다.

아직 댓글이 없습니다.