« Prev : 1 : 2 : 3 : 4 : Next »

이 글은 lsof 의 사용방법에 대해 설명합니다. lsof 는 프로세스의 파일핸들을 조사해 볼 수 있는 유용한 툴입니다.

lsof ("LiSt Open Files") 는 서버에 열린 파일 핸들의 리스트를 보여주는 툴입니다. 여러가지 옵션들과 스위치들을 통해서 이러한 핸들들을 필터링할 수 있게 해줌으로써 솔라리스 관리자가 문제에 대한 분석을 가능하도록 도와 줍니다.

이 가이드는 lsof 의 몇가지 커맨드라인 옵션에 대해 설명합니다. 그리고 실전에서 어떻게 lsof 를 사용할 수 있는지에 대한 몇가지 예제를 보여 드립니다. (참고: 이 글의 모든 예제는 솔라리스 8 버전 이상에서 모두 적용 가능합니다; 이전 버전에서도 사용이 가능할 것으로 생각되지만 직접 확인해 보진 않았습니다.)

"lsof" 얻기

lsof 는 기본 솔라리스 설치의 표준으로 따라서 설치되지 않습니다. 그러나 SPARC 및 x86 버전의 솔라리스 패키지로 컴파일 가능하고 http://sunfreeware.com 에서 다운로드 받으실 수 있습니다.

열린 네트워크 포트 확인하기

구문:

 
lsof -i [<protocol>][@<interface name>][:<port>]

위의 3가지 파라미터를 일부분만 혹은 전부 지정하실 수 있습니다. 생략된 부분은 와일드카드로 간주 합니다. <port> 는 단일 포트 혹은 범위로 지정될 수 있습니다. lsof 를 이러한 방식으로 사용하는 것은 netstat -a 와 비슷한 결과를 돌려주지만 거기에 덧붙여서 프로세스와 소유자의 정보 또한 제공 합니다.

주어진 프로세스가 연 파일 핸들들의 리스트

구문:

 
lsof -p <process id>[,<process id>[,<process id>[...]]]

lsof 에 하나 혹은 복수개의 프로세스 ID 를 (콤마로 구분됨) 입력함으로써 모든 연관된 파일 핸들들의 리스트를 출력할 수 있습니다. 이것은 특정 실행 프로세스가 어떠한 라이브러리를 사용하는지 확인할때 아주 유용합니다. 이 커맨드를 통해서 프로세스가 어떻게 로그 파일, 설정 파일들과 상호동작하는지 확인하실 수 있습니다.

특정 유저가 연 파일 핸들들의 리스트

구문:

 
lsof -u <username>[,<username>[,<username>[...]]]

이 커맨드는 주어진 유저에게 속한 모든 열린 핸들들을 보여 줍니다.

주어진 파일 시스템에서 열린 모든 파일 핸들들 보기

구문:

 
lsof <file system or device>

이 옵션은 umount 커맨드가 수행되는 것을 막는 프로세스들을 찾을때 유용합니다. 혹은 적절한 디렉토리 항목에 없는 열린 파일을 추적할때에 유용합니다.

다른 유용한 플래그들
  • -b – 커널을 블록할 수 있는 시스템 호출의 사용 회피하기
  • -w – 주의 메세지 생략하기
  • -P – 포트 번호를 /etc/services 에 있는 서비스 이름들과 매핑하지 말기
  • -a – 이 플래그를 다른 두 플래그 사이에 삽입함으로써 두가지 플래그 모두에 매치되는 결과만 보기. 기본적으로 lsof 는 지정된 플래그들 중에 하나라도 만족하는 모든 핸들들을 보여줌.
예제

inetd 가 리스닝하고 있는 모든 포트들 보기:
현재 inetd 가 어떠한 포트들을 열고 있는지 확인해 봅시다.

 
gouda# ps -ef | grep inetd
 
root  2849     1  0   May 25 ?        6:43 /usr/sbin/inetd -s
gouda# lsof -i -a -p 2849
COMMAND  PID USER   FD   TYPE        DEVICE SIZE/OFF NODE NAME
inetd   2849 root   11u  IPv6 0x30006ec96d0      0t0  TCP *:ftp(LISTEN)
inetd   2849 root   13u  IPv4 0x30006ec9550      0t0  UDP *:name(Idle)
inetd   2849 root   16u  IPv4 0x30008f26ad8      0t0  TCP *:52783(LISTEN)
inetd   2849 root   17u  IPv4 0x30006ec9b50      0t0  UDP *:57504(Idle)
inetd   2849 root   23u  IPv6 0x30008f264d8      0t0  UDP *:servicetag(Idle)
inetd   2849 root   24u  IPv4 0x30008f26358      0t0  TCP *:servicetag(LISTEN) 

일단 inetd 의 프로세스 ID 를 확인하고, 그 다음 lsof 가 모든 IP 핸들들과 (-i) 또한 (-a) 와 같이 포트에 의해 열린 것들을 (-p <process id>) 확인합니다.

특정 유저의 현재 열린 모든 네트워크 접속의 리스트:
가능한 보안 구멍을 추적하거나 어플리케이션이 올바른 데이타베이스에 접속하고 있는지 확인하기 위해서, lsof 는 주어진 유저의 현재 네트워크 접속들을 보여 줍니다.

 
gouda# lsof -i -a -u fred
COMMAND PID USER FD  TYPE DEVICE SIZE NODE NAME
sshd   9696 fred  5u IPv4 0x3001 0t527 TCP gouda:22->edam:46528(ESTABLISHED)
sshd   9696 fred 10u IPv4 0x300e   0t0 TCP localhost:6011(LISTEN)
sshd  14710 fred  5u IPv4 0x3008 0t404 TCP gouda:22->edam:46590(ESTABLISHED)
sshd  14710 fred 10u IPv4 0x307d   0t0 TCP localhost:6012(LISTEN)
sshd  17013 fred  5u IPv4 0x300f 0t146 TCP gouda:22->edam:50019(ESTABLISHED)
sshd  17013 fred 10u IPv4 0x30e0   0t0 TCP localhost:6010(LISTEN)
ssh   25259 fred  4u IPv4 0x3000 0t157 TCP gouda:54435->colby:22(ESTABLISHED)
sshd  25383 fred  5u IPv4 0x3000 0t126 TCP gouda:22->brie:34480(ESTABLISHED)
ssh   25438 fred  4u IPv4 0x3000  0t91 TCP gouda:54448->smokey:22(ESTABLISHED)

이 것은 fred 란 유저가 3개의 수신(incoming) ssh 접속을 가지고 있고 두개의 송신 ssh 접속을 가지고 있음을 알려 줍니다. lsof 를 다른 서버중에 하나에서 실행하고, 본래 포트를 찾아 봄으로써 (예를 들어 edam 의 포트 46528) 거기서 계속적으로 추적을 수행할 수 있습니다.

어떤 프로세스가 특정 파일 시스템의 언마운트를 막는지 찾아보기:
특정 프로세스가 umount 커맨드의 수행을 방해할 수 있습니다. -f 플래그를 통해서 잠재적으로 오류를 유발하는 대신에 lsof 는 어떠한 프로세스들이 먼저 정지 되어야 하는지를 보여 줍니다.

 
gouda# lsof /mnt/scratchdisk
COMMAND   PID USER    FD  TYPE DEVICE SIZE/OFF NODE NAME
bash     7268 fred    cwd VDIR 85,204      512    2 /mnt/scratchdisk/edam
dcm     15375 george  txt VREG 85,204   292352  202 /mnt/scratchdisk/bin/dcm
dcm     15375 george  cwd VDIR 85,204      512    5 /mnt/scratchdisk/bin/dcm

결과는 fred 가 배시 쉘을 가지고 있고 우리의 마운트 포인트 위에서 작업하고 있음을 보여 줍니다. 그리고 george 가 동일한 파일 시스템상의 다른 디렉토리에서 dcm 의 복사를 시작하였습니다.

특정 포트에 어떠한 프로세스가 리스닝하고 있고 누가 이 포트를 사용하고 있는지 보기:
포트가 이미 사용되고 있습니다(port already in use) 오류 때문에 데몬이 시작되지 않을때 관리자는 종종 좌절하게 됩니다. lsof 는 어떤 프로세스가 우리가 사용하고자 하는 포트를 사용하고 있는지 추적하기 위해 사용될 수 있습니다.

 
gouda# lsof -i :7507
COMMAND  PID   USER FD  TYPE  DEVICE  SIZE NODE NAME
inetd    668   root 34u IPv4 0x303f0   0t0  TCP *: 7507 (LISTEN)
answer 19757 nobody  0u IPv4 0x58028 0t132  TCP gouda:7507->edam:46111 (ESTABLISHED)
answer 19757 nobody  1u IPv4 0x58028 0t132  TCP gouda:7507->edam:46111 (ESTABLISHED)
answer 19757 nobody  2u IPv4 0x58028 0t132  TCP gouda:7507->edam:46111 (ESTABLISHED)

위의 결과로 볼때 inetd 가 answer 라는 서비스를 그 포트에서 실행하고 있고 edam 에서 실행되는 어떤 것이 접근하고 있음을 알 수 있습니다.edam 에서 lsof -i :46111 를 수행하여 어떠한 프로세스 인지를 확인해 봅니다.

해당되는 디렉토리 항목이 없는 열린 파일을 참조하는 프로세스 찾아내기:
만약 어떤 유저가 실행중인 프로세스가 참조하는 파일을 지웠다면, 파일 시스템은 실제로 마지막 링크가 닫힐때 까지 이 파일을 삭제하지 않습니다. 이러한 경우 실행중인 프로세스만이 남게 됩니다. 만약 이 프로세스를 찾을 수 있다면 우리는 해당 프로세스를 닫거나(파일이 삭제되길 원할때) 혹은 파일을 다시 살려야 할때 /proc 파일 시스템(솔라리스 8 이상) 을 통해서 파일의 내용을 저장할 수 있습니다.

 
gouda # df -k /opt/myapp/data
Filesystem            kbytes    used   avail capacity  Mounted on
/dev/md/dsk/d100     4129290 1458133 2629865    36%    /opt/myapp
 
gouda # lsof /opt/myapp | grep '/dev/md/dsk/d100'
less      15043 fred    4r  VREG  102,0       144 2050050 /opt/myapp (/dev/md/dsk/d100)

위의 결과는 파일이 less (프로세스 ID 15043) 에 의해 열려져 있음을 알려 줍니다. 만약 파일을 삭제하는 것이 목표라면 less 프로세스를 종료 시킴으로써 원하는 작업을 수행할 수 있습니다. 만약 파일의 내용을 다시 살리는게 목표라면, 복사를 통해서 가능합니다. 4번째 컬럼은 파일 디스크립터 4번에 읽기 전용 핸들을 보여 줍니다. 이것은 /proc/15043/fd/4 를 읽음으로써 파일의 내용을 다시 살릴 수 있음을 의미 합니다.


이 글의 영문 원본은
wikis.sun.com Using "lsof" in the Real World
에서 보실 수 있습니다.

2010/02/18 13:21 2010/02/18 13:21
neosky 이 작성.

당신의 의견을 작성해 주세요.

[로그인][오픈아이디란?]
오픈아이디로만 댓글을 남길 수 있습니다

복사  ESC + yy
붙여넣기  ESC + p
삭제  ESC + dd
단어삭제  ESC + dw
삽입  ESC + i

앞넘기기  CTRL+ f         y (한줄)
뒤넘기기  CTRL + u       j (한줄)
현재파일정보 보기 CTRL + g
2009/11/13 01:11 2009/11/13 01:11
neosky 이 작성.

당신의 의견을 작성해 주세요.

[로그인][오픈아이디란?]
오픈아이디로만 댓글을 남길 수 있습니다
어느날 yum 패키지 업데이트 이후 MRTG 그래프가 그려지지 않을 때가 있다.

필자는 MRTG를 스크립트에 넣어 간접적으로 CRONTAB에서 5분 단위로 실행하게끔 설정해두었다.

/usr/bin/perl /usr/bin/mrtg /home/admin/mrtg/cfg/mrtg.cfg --logging /var/log/mrtg.log


수동으로 스크립트를 실행하여도 다음과 같이 로그가 찍힌채로 갱신이 되지 않았다.

mrtg.log

2009-11-13 00:50:16 -- List::Util object version 1.21 does not match bootstrap parameter 1.19 at /usr/lib/perl5/5.8.8/i386-linux-thread-multi/XSLoader.pm line 94.

위 파일의 라인에서 잘못을 찾으라는데... ㅡㅡ;


구글링 검색후 다음과 같이 스크립트를 변경해준 이후 해결되었다.

/usr/bin/mrtg /home/admin/mrtg/cfg/mrtg.cfg

--logging 달아줬을때는 마찬가지로 에러 메세지가 발생하면서 MRTG 갱신이 되지 않아 떼버렸다.


2009/11/13 01:04 2009/11/13 01:04
neosky 이 작성.

당신의 의견을 작성해 주세요.

[로그인][오픈아이디란?]
오픈아이디로만 댓글을 남길 수 있습니다
dd if=/dev/원래하드... of=/dev/복사될..새하드
dd if=/dev/sda1 of=/dev/sdc1


또는

cat /dev/sda > /dev/sdc


2009/11/03 17:56 2009/11/03 17:56
neosky 이 작성.

당신의 의견을 작성해 주세요.

[로그인][오픈아이디란?]
오픈아이디로만 댓글을 남길 수 있습니다
아래와 같이 적어주면 압축해제된 파일만 삭제된다고 한다.

tar tfz filename.tar.gz | xargs rm


 

2009/11/03 13:36 2009/11/03 13:36
neosky 이 작성.

당신의 의견을 작성해 주세요.

[로그인][오픈아이디란?]
오픈아이디로만 댓글을 남길 수 있습니다

curl -o /dev/null -s -w %{time_connect}:%{time_starttransfer}:%{time_total} http://www.yahoo.com

0.306:0.604:0.901
2009/11/03 13:30 2009/11/03 13:30
neosky 이 작성.

당신의 의견을 작성해 주세요.

[로그인][오픈아이디란?]
오픈아이디로만 댓글을 남길 수 있습니다
사용자 삽입 이미지

dstat

# dstat -tapli --tcp --ipc -M topmem

-M 옵션은 external module 목록이며, 이를 알려면 # dstat --list 해보면 된다.



battery, cpufreq, dbus, freespace, gpfs, gpfsop, helloworld, innodb_buffer, innodb_io, innodb_ops, lustre, mysql5_com, mysql5_conn, mysql5_io, mysql5_keys, mysql_io, mysql_keys,
        net_packets, nfs3, nfs3op, nfsd3, nfsd3op, postfix, rpc, rpcd, sendmail, snooze, test, thermal, topbio, topcpu, topio, topmem, topoom, utmp, vmkhba, vmkint, vmknic, vmmemctl, vzcpu, vzubc,
        wifi


각 배포판별 RPM 패키지를 제공하며, 첨부파일은 TAR 압축파일이다.
링크참조
http://dag.wieers.com/home-made/dstat/#download


dstat-0.6.9.tar.bz2

dstat-0.6.9.tar.bz2

2009/11/03 13:14 2009/11/03 13:14
neosky 이 작성.

당신의 의견을 작성해 주세요.

[로그인][오픈아이디란?]
오픈아이디로만 댓글을 남길 수 있습니다

#!/bin/bash

# dimeclub.co.kr 으로 쌓이는 weblog를 3일 단위로만 저장하고
# 그 이전의 로그는 지우도록 하는 스크립트
# 작성일 : 2009.08.10

## 설정값
DIR1="/backup/weblog/seroot_www";
DIR2="/backup/weblog/seroot_blog"
DEL_DAY="3";
timefile="/tmp/.time.tmp";

## 오래된 파일 값 삭제 (3일 이전)
touch -t $(date +%Y%m%d%H%M --date "$DEL_DAY days ago") $timefile;

echo "오늘로부터 $DEL_DAY 일 이전의 자료를 삭제합니다."

find $DIR1 -type f -name "*" ! -newer $timefile -exec rm -f {} \;
find $DIR2 -type f -name "*" ! -newer $timefile -exec rm -f {} \;

rm -f $timefile;


위 스크립트를 짜서 cron.daily 에 넣어두면 알아서 3일전 파일은 삭제가 될 것이다.

2009/08/10 16:43 2009/08/10 16:43
neosky 이 작성.

당신의 의견을 작성해 주세요.

[로그인][오픈아이디란?]
오픈아이디로만 댓글을 남길 수 있습니다
사용자 삽입 이미지

2009/07/28 11:50 2009/07/28 11:50
neosky 이 작성.

당신의 의견을 작성해 주세요.

[로그인][오픈아이디란?]
오픈아이디로만 댓글을 남길 수 있습니다
rm -rf * 명령으로 해당 디렉토리의 파일 삭제시 파일이 너무 많아서 나타나는 현상으로

다음과 같은 명령으로 파일 갯수 단위를 끊어 삭제할 수 있다.


ls | xargs -n 1000 rm -f


☞ ls 로 1000개씩 나눠서 삭제하라.

또는

echo * | xargs rm -rf

 
 
2009/07/22 09:24 2009/07/22 09:24
neosky 이 작성.

당신의 의견을 작성해 주세요.

[로그인][오픈아이디란?]
오픈아이디로만 댓글을 남길 수 있습니다
« Prev : 1 : 2 : 3 : 4 : Next »