RSS구독하기:SUBSCRIBE TO RSS FEED
즐겨찾기추가:ADD FAVORITE
글쓰기:POST
관리자:ADMINISTRATOR
'Linux'에 해당되는 글 112
출처 블로그 > kdnnetwork님의 블로그
원본 http://blog.naver.com/kdnnetwork/140000675195
제 목 : 서버 모니터링 툴의 강자, RRDtool 가이드 (작성중. alpha 버전)
작성자 : 좋은진호(truefeel)
작성일 : 2003.9.22(월)~

그래픽 모니터링 툴인 RRDtool과 그 프론트엔드 툴 HotSaNIC의 설치, 운영가이드이다.

1. RRDtool의 이해
2. RRDtool 설치
3. HotSaNIC 설치
4. RRDtool 직접 다루기
5. 문제 해결
6. 이용 사례



1. RRDtool의 이해

RRDtool에 대해 들어가기 전에 먼저 MRTG 툴을 설명할 필요가 있을 듯 하다.
MRTG(Multi Router Traffic Grapher)는 이름에서도 드러난대로, SNMP 프로토콜을 사용하여
라우터를 거쳐가는 트래픽을 실시간 그래픽을 통해 모니터링하는데 가장 많이 사용한다.
이외에 시스템을 모니터링하는 여러 addon들이 있다.
DISK 사용량, CPU사용량, 메모리 사용량, 데몬, 세션 개수 등..
심지어는 P2P인 당나귀의 트래픽, 프락시 서버인 Squid 트래픽까지 실시간(실시간이라기
보다는 특정 시간간격으로 변화하여 보여준다는게 더 정확하지만)으로 웹에서 볼 수 있다.

RRDtool은 MRTG처럼 실시간 그래픽 모니터링 기능을 가지고 있으면서 보다 더 개선된 형태의
툴이다. 보다 빠르고 시스템 로드를 덜 잡아먹는다. 또한 MRTG의 제약이었던 2개 이상의 데이터를
하나의 그래픽을 통해 표시할 수 있다. 그래픽의 유연성(?)면에서도 단연 RRDtool이 압도한다.

[ MRTG로 트래픽 모니터링하는 화면 ]


[ RRDtool과 HotSaNIC으로 CPU 사용률을 모니터링하는 화면 ]


2. RRDtool 설치

RRDtool :
http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/

RRDtool의 시스템 요구사항은 다음과 같다.

Perl 5.005 (컴파일시에 문제가 발생하면 더 최신 것을 설치해본다.)
GNU make
GNU gcc

위 RRDtool 사이트에서 최신 버전을 받아온다. /usr/local/rrdtool에 하는 것으로 가정한다.


# tar xvfz rrdtool-1.0.45.tar.gz
# cd rrdtool-1.0.45
# ./configure --prefix=/usr/local/rrdtool
# make install
# make site-perl-install
... 중략 ...
Installing /usr/lib/perl5/site_perl/5.8.0/RRDp.pm
Installing /usr/share/man/man3/RRDp.3pm
... 생략 ...


3. HotSaNIC 설치

HotSaNIC :
http://hotsanic.sourceforge.net/archive/

HotSaNIC은 RRDtool을 사용하는 툴로 시스템 통계정보를 그래프로 생성해준다.

* 시스템 요구 사항

- RRDtool
- iptables 또는 ipchains (네트워크 트래픽 통계용으로 쓰기 위함)

위 사이트에서 받은 최신 버전은 컴파일없이 환경설정만으로 바로 사용하므로
/usr/local에서 압축을 푼다.


# cd /usr/local
# tar xvf HotSaNIC-0-5-0-pre3.tgz ( HotSaNIC/ 디렉토리가 생성된다. )
# cd HotSaNIC



1) 제공하는 모듈

HotSaNIC은 어떤 모듈을 통해 시스템 통계를 제공하는지 알아보고,
그 모듈을 사용할 것인지 안할 것인지를 판단해보자.


---------   ----------------------------------------------------------- ---------------
모듈      처리하는 통계 정보                      truefeel의 권장
---------   ----------------------------------------------------------- ---------------
APCUSV    APC UPS의 현황 (apcaccess 툴 사용)             N
         (APC UPS를 사용하지 않고 또한 있더라도 서버와 연결하여

                   모니터링중이 아니라면 N)
APPS     데몬, 응용프로그램별 프로세스 현황                Y
          (프로세스 이름 별도 설정 필요)
DISKIO     각 HDD별(파티션별이 아님) 입출력                   Y
         (별도 설정 필요)
DNET     Distributed.Net관련 RC5, OGR, DES, CSC ???         N
NETWORKS  네트워크 트래픽 (별도 설정 필요)                     Y
PART    파티션별 사용량                                  Y
PING     지정한 서버로 ping time 결과 (ping서버 설정 필요)        ping할 서버가

                                                                                                           있다면
SENSORS CPU, 마더보드 등의 온도, 전압등의 수치              원하는대로
SHOUTCAST 지정한 서버와 포트로의 스트링 현황 (서버, 포트 설정 필요)  N
SYSTEM  시스템의 프로세스 수, CPU 사용률, load, 메모리 사용률, ...      Y
TRAFFIC  네트워크 인터페이스별(eth0, ...) 트래픽                   Y
       (SNMP를 통해 라우터나 다른 서버의 트래픽도 모니터링 가능,
         물론 이 때는 별도 설정 필요)
WORMS  웹로그 파일을 이용한 님다, 코드레드 등의 웜 공격 건수           Y
      (웹로그 경로 설정 필요. 문자열 지정으로 다른 웜 공격도 설정 가능)
--------- ----------------------------------------------------------- ----------------


2) setup.pl로 기본 환경 파일 생성

이제 setup.pl 으로 기본 환경 설정을 해보자.
과정은 길지만 간단하다. 모듈을 보고 Y로 할 것인, N로 할 것인지를 결정한다.
이 설정은 나중에 ./setup.pl으로 변경할 수 있으므로 맘 편하게 진행해라.
(반복되는 내용이라 메시지 중간중간 생략하였다.)


# ./setup.pl
Configuring modules:


Module found: APCUSV
----------------------------------------
Do you want to use this module ? (Y)es / (n)o > n

Module found: APPS
----------------------------------------
Do you want to use this module ? (Y)es / (n)o >
Do you want to show this module's graphs on the webpage ? (Y)es / (n)o >

... 중략 ...

Module found: DISKIO  ... 중략 ...
Module found: DNET   ... 중략 ...
Module found: NETWORKS
----------------------------------------
Do you want to use this module ? (Y)es / (n)o >
Do you want to show this module's graphs on the webpage ? (Y)es / (n)o >

setting up networks ...

Configuring local interfaces.
(i)nternal means an interface pointiong to your local machines (intranet)
(e)xternal means an interface connecten with the internet
(n)one means you don't want to account this interface.

Please answer these:
found: eth0 - (i)nternal, (e)xternal or (n)one ? e

found: lo - (i)nternal, (e)xternal or (n)one ? n

... 중략 ...

Module found: PART   ... 중략 ...
Module found: PING   ... 중략 ...
Module found: SENSORS  ... 중략 ...
Module found: SHOUTCAST ... 중략 ...
Module found: SYSTEM  ... 중략 ...
Module found: TRAFFIC
----------------------------------------
Do you want to use this module ? (Y)es / (n)o >
Do you want to show this module's graphs on the webpage ? (Y)es / (n)o >

setting up traffic ...

Configuring local interfaces. Please answer these:
found: eth0 - (y)es or (n)o ? y

found: lo - (y)es or (n)o ? n


Please check the settings file and adapt it to satisfy your needs.
If you have any interfaces slower than 100 MBit, please change the
corrosponding default values.

... 중략 ...

Module found: WORMS  ... 중략 ...
----------------------------------------
Ok.
Writing main settings ...
 checking for OS-type (current: not configured)
OSTYPE="Linux"
 checking path to "rrdtimer" (current: not configured)
DAEMONDIR="/usr/local/HotSaNIC"
 checking path to "rrdtool" (current: not configured)
the following possibilities have been detected:
0 /usr/bin
1 /usr/local/rrdtool/bin

which one shall i use (0=default ... 1) ? > 1 ( rrdtool이 2군데 설치된 경우이다.)
BINPATH="/usr/local/rrdtool/bin" (RRDtool 실행이 있는 디렉토리)
LOGDIR="$DAEMONDIR/var/log/"   (로그가 저장될 디렉토리)
PIDFILE="$DAEMONDIR/var/rrdtimer.pid"
DIAGRAMLOG="last"
LOGSIZE="200000"
LOGBACKUPS="5"
DEBUGLEVEL="-1"
STIME="120"
SCHEDULE_MIN="100"
SCHEDULE_MAX="200"
RUN="apcusv apps diskio dnet networks part ping sensors shoutcast system traffic worm
s"
WEBDIR="not configured"
WIDTH="600"
HEIGHT="200"
IMAGEFORMAT="gif"
SHOW="apcusv apps diskio dnet networks part ping sensors shoutcast system traffic wor
ms"
ORDER="traffic system part ping dnet sensors"
DTIME="15" (15분 간격으로 이미지를 갱신한다.)
CTIME="24" (24시간 간격으로 통계화면 메인에 표시될 작은 크기의 이미지를 갱신한다.)
 guessing convert method...
 checking for Image::Magick perl module... not found
 checking path to "convert" from ImageMagick (current: not configured)
detected: /usr/bin/convert
is this corrrect? (y)
 checking path to "snmpwalk" (current: not configured)
detected: /usr/bin/snmpwalk
is this corrrect? (y)
SNMPWALK="/usr/bin/snmpwalk"
 checking path to "snmpget" (current: not configured)
detected: /usr/bin/snmpget
is this corrrect? (y)
SNMPGET="/usr/bin/snmpget"
checking path to "snmpbulkwalk" (current: not configured)
detected: /usr/bin/snmpbulkwalk
is this corrrect? (y)
SNMPBULKWALK="/usr/bin/snmpbulkwalk"

--- Main settings generated. ---

Writing start/stop script "rrdgraph" ... Ok.

Now adapt all settings files to satisfy your needs.
They are all linked to the directory /var/settings .


3) 필요한 디렉토리 생성

이제 RRDtool의 웹용 이미지와 html이 저장될 디렉토리와 로그 파일 저장 디렉토리를 생성한다.
디폴트로 로그는 HoSaNIC 홈의 var/log에 생성된다.
(html 홈은 /usr/local/apache/htdocs/ 라고 가정)


# mkdir /usr/local/apache/htdocs/rrdtool
# mkdir var/log


4) 환경 파일의 주요 설정

HoSaNIC 홈/settings가 주 설정 파일이고
HoSaNIC 홈/modules/모듈명/settings는 각 모듈별 설정 파일이다.

주 settings 파일에서 주요 설정을 살펴보자.(반드시 확인할 것에 * 표시해둠)


# BINPATH  = rrdtool 실행 파일이 있는 경로 (*)
BINPATH="/usr/local/rrdtool/bin"

# LOGDIR   = HoSaNIC의 로그 파일 경로
# LOGSIZE  = 로그 파일 크기
# LOGBACKUPS = 지정한 개수만큼 로그는 로데이터션되어 백업된다.
#       로그 파일명은 HotSaNIC.log, HotSaNIC.log.1, ...
LOGDIR="$DAEMONDIR/var/log/"
LOGSIZE="200000"
LOGBACKUPS="5"

# RUN  = 실행할 모듈 목록 (*)
# SHOW = 웹페이지로 표시할 모듈 목록 (*)
# ORDER = 표시할 모듈의 순서를 지정(먼저 쓴 것부터 왼쪽에 표시함)
RUN="apps diskio networks part ping sensors system traffic"
SHOW="apps diskio networks part ping sensors system traffic"
ORDER="traffic system part ping sensors"

# WEBDIR   = 생성된 이미지, html이 저장될 디렉토리 (*)
# IMAGEFORMAT = 이미지 파일 형식 (gif 또는 png)
WEBDIR="/usr/local/apache/htdocs/rrdtool"
IMAGEFORMAT="gif"

# DTIME = 지정한 간격으로 이미지를 생성한다. (단위는 분)
# CTIME = 지정한 간격으로 모니터링 메인화면의 작은 이미지를 생성한다. (단위는 시간)
#     따라서 처음 설치한 후 지정한 시간내에 convert.pl 명령을 하지 않으면 메인화면의
#     이미지는 최소 지정 시간동안 볼 수 없다.
DTIME="15"
CTIME="24"

# CONVERTPATH = ImageMagick 를 사용하여 이미지를 생성한다. convert 경로를 지정한다.
CONVERTPATH="/usr/bin/convert"

# REFRESH = 지정한 초단위로 웹페이지를 리프레쉬해서 보여준다. 기본 300초(5분)
REFRESH="300"



각 모듈별 설정은 해당 디렉토리의 settings을 보면 자세히 설명이 되어 있다.
여기서는 ping, diskio, apps에 대해서만 예를 들어본다.

* ping 모듈 ( HoSaNIC홈/modules/ping/settings )

 192.168.123.15(파일서버)에 대해 ping을 한다면, 다음을 추가하면 된다.


HOST=192.168.123.15,File Server


 설정했는데 ping 이미지가 생성안된다면 '5. 문제해결'에 해결방법을 설명해뒀다.

* diskio 모듈 ( HoSaNIC홈/modules/ping/settings )

/proc/stat 에서 disk_io 라인을 살펴보면 다음과 같이 되어 있다.

disk_io: (2,0):(1,1,2,0,0) (3,0):(306090,39930,942826,266160,5212040)
(3,1):(55015,28746,1435800,26269,909568) (8,0):(50,50,253,0,0)

여기서 (3,0) = hda, (3,1) = hdb, (8,0) = sda를 각각 의미한다.
따라서 hda와 hdb의 disk 입출력을 보려면 다음과 같이 설정한다.


DEV=3_0,hda
DEV=3_1,hdb


* apps 모듈 ( HoSaNIC/modules/apps/settings )


APP=httpd,Apache
APP=sendmail,Sendmail
APP=mysqld,Mysql Server
APP=hanterm,hanterm
APP=xmms,xmms
APP=MozillaFirebird-bin,Mozilla Web Browser


5) 실행

자~ 이제 웹페이지를 생성하고 rrdgraph만 실행하면 모니터링할 수 있다.


# ./makeindex.pl
# ./rrdgraph start



이제 웹브라우저를 띄우고 보면 된다. 아직 이미지도 안나온는데 뭘 보라는 것일까?
최소 15분(settings의 DTIME)이 지내야 모듈내의 큰 이미지들이 생성되고
24시간(CTIME)이 지나면 메인의 작은 이미지가 보일 것이다.
24시간 전이라도 적당한 시기에 ./convert.pl을 실행하면 메인에서도 이미지를 볼 수 있다.

부팅할 때 자동으로 rrdgraph가 실행되록 하려면 어떻게 해야할까?
rrdgraph 스크립트를 /etc/rc.d/init.d 에 복사를 한 후 chkconfig로 서비스를 추가한다.


# cp rrdgraph /etc/rc.d/init.d
# chkconfig -add rrdgraph



4. RRDtool 직접 다루기

HoSaNIC은 이미 정해진 모듈을 통해서 RRDtool을 다루는 것이다.
이제 시스템관리자가 원하는 데이터를 RRDtool로 직접 조작하여 통계용 이미지를 생성하는
방법을 알아본다. 간단히 과정을 정리해보면.

- RRDtool용 자체 DB(일반적으로 .rrd로 지정)를 생성한다.(create) ->
- 데이터를 업데이트하거나 (update) 가져온다.(fetch) ->
- 이미지를 생성한다. (graph)

1) rrdtool 명령 익히기

DB 생성, 이미지 만드는 것은 모두 RRDtool홈/bin/rrdtool 명령을 통해서 한다.


* 형식 : rrdtool [명령] [명령 옵션...]
* 예  : rrdtool create coffeenix_status.rrd DS:....


rrdtool에서 사용 가능한 명령은 무엇이 있을까?


---------- -----------------------------------------------------------------------
명 령   설 명
---------- -----------------------------------------------------------------------
create   새로운 RRD DB를 만든다.
update   DB에 새 데이터를 저장한다.
graph    저장된 DB자료를 이용해서 이미지를 생성한다. (.gif 또는 .png)
dump    RRD DB의 데이터를 XML 포맷으로 뽑아준다.
restore   XML 포맷에서 RRD DB로 저장한다.
fetch    RRD DB에서 데이터를 얻어온다.
tune    RRD DB의 설정을 변경한다.
last    RRD DB의 최종 업데이트 시간을 알려준다.
info    RRD DB의 헤더 정보를 보여준다. (파일명, 최근업데이트일, 설정값...)
rrdresize  RRA 크기를 변경한다. 가능하면 사용하지 말기를
xport    RRD DB의 데이터를 XML 포맷으로 뽑아준다. (출력 포맷 지정)
---------- -----------------------------------------------------------------------


2) 샘플 DB 생성

3) 이미지 만들기

5. 문제 해결

1) HoSaNIC 로그 파일을 보니 Can't locate RRDs.pm in @INC (@INC contains... 오류가 있습니다.

  RRDtool 설치할 때 make site-perl-install 를 하지 않아 RRDs.pm 펄 모듈이
  설치되지 않아서 입니다.
  RRDtool 소스 디렉토리에 가서 make site-perl-install을 하세요.
 
2) makeindex.pl 실행할 때 다음 오류가 발행합니다.
  WEBDIR (path to HotSaNIC's output directory) does not exist.

  시스템 모니터링 결과가 저장될 웹디렉토리를 생성하지 않았다.
  위 글중 '3 - 3) 필요한 디렉토리 생성'을 확인해봐라.

3) 시간이 한참지났는데 ping 이미지가 생성이 안됩니다. 물론 ping설정은 했습니다.
  로그를 보니 Can't locate asm/unistd.ph in @INC (did you run h2ph?).. 가 있습니다.

  펄용 헤더 파일이 없기 때문입니다. 펄 헤더로 변환해주는 h2ph로 해결할 수 있습니다.

  cd /usr/include; h2ph -r -l .

6. 이용 사례

  • http://kornet.hanirc.org/chanstat/
     HanIRC의 채널별 사용자 통계를 보여준다. 5분간격의 데이터를 1시간 단위로 자동 업데이트한다.
     장혜식님의 py-rrdtool을 사용한 페이지
    http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/gallery/

    * 참고 자료
  • RRDtool 매뉴얼
     
    http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/manual/index.html
  • itup님의 RRDtool 튜토리얼, 논문 자료
     
    http://myhome.hanafos.com/~itup/index.html
  • 이은태님의 'RRDTool로 서버의 상황을 파악하자.'
     
    http://kltp.kldp.org/stories.php?story=03/02/13/1717339

  • 2006/09/08 23:32 2006/09/08 23:32
    이 글에는 트랙백을 보낼 수 없습니다
    출처 블로그 > 미소
    원본 http://blog.naver.com/osang1997/40007954085
    보내고 받는 메일의 양 제한하기

    시스템의 제한 설정과  서비스의 안정성은 매우 깊은 연관성을 가지고 있다. 기본적으로 대부분의 서비스는 유저가 사용 가능한 시스템의 자원 제한이 거의 설정되어 있지 않은데, 메일 서비스도 마찬가지이다.
    최근에는 메일의 이용율이 높아지고, 메일의 컨텐츠도 전통적인 텍스트 방식에서 음성,이미지등 각종 동영상이 주종을 이루면서 용량도 점점 커지고 있다. 물론 그만큼 하드웨어나 메일 서버의 소프트웨어적인 성능도 향상되고 있지만  용량이 큰 메일을 주고 받는다면 당연히 시스템의 부하가 올라가기 마련이고 이로 인하여 같은 서버내 다른 서비스에까지 영향을 미치게 된다.  따라서 시스탬에서 보내는 메일 서비스(SMTP)나 받는 메일 서비스(POP3)를 제공하고 있다면 용량이 큰 파일을 주고 받는 것을 적절히 제한할 필요가 있다.

    sendmail 은 로컬의 메일을 외부로 발송하는 SMTP(보내는 메일서버) 기능도 있
    지만 외부에서 서버내 계정으로 전송되는 메일을 받아서 서버에 저장하는 기능
    도 있다. 이때 기본적으로는 보내거나 받는 메일의 양에 대한 제한이 전혀 없
    어 10메가 이상이 넘는 큰 사이즈의 메일이 송 수신 될 경우 서버에 과부하가
    걸릴 수 있으므로 아래와 같이 각각의 설정(보내는 메일과 받는 메일의 양)
    을 적절히 제한하여 설정하는 것이 좋다.

    >> SMTP 서버에서 보내는 양 제한하는 법.

    /etc/mail/sendmail.cf (또는 /etc/sendmail.cf. 이는 sendmail 의 패키징 방
    법에 따라 다르다.) 파일에서 다음과 같이 MaxMessageSize 부분의 주석을 제거
    하고 제한하고자 하는 적절한 값을 입력한다.

    # maximum message size
    O MaxMessageSize=5024000

    위와 같이 설정하였을 경우 현재의 서버를 보내는 메일 서버로 이용시 첨부 파
    일이 5M 이상 초과하거나 웹에서 /usr/sbin/sendmail 을 실행하여 외부로 메일
    을 발송하는 메일링 리스트등의 프로그램에서도 메일 발송시 5 메가 이상의 메
    일은 보낼 수 없게 된다.
    5024000 은 byte 단위이며 설정 변경 후 변경된 내용을 적용하려면 killall –
    HUP sendmail 로 sendmail 데몬을 Refresh 하면 된다.

    >> 받는 메일 서버에서 받는 양 제한하는 법.

    외부에서 서버로 들어오는 메일에 대해서 용량을 제한하고 싶다면 같은 파일
    (sendmail.cf) 에서 "Local and Program Mailer specification" 부분을 설정
    해 주면 된다.

    Mlocal, P=/usr/bin/procmail, F=lsDFMAw5:/|@qSPfhn9, S=10/30,
    R=20/40, M=5024000, T=DNS/RFC822/X-Unix, A=procmail -Y -a $h -d $u

    위와 같이 T=DNS/RFC822/X-Unix  앞부분에 M=5024000 부분을 추가해 주면 된
    다.
    마찬가지로 5024000는 byte 단위이며 각자의 시스템 환경에 따라 원하는 용량
    만큼 적절히 설정해 주면 된다   역시 설정 변경 후 sendmail 을 refresh 하
    면 적용이 된다.
    위의 경우 서버에서는 5메가 이상의 메일은 수신하지 않으며 5메가 이상의 메
    일을
    보낸 이는

    552 5.2.3 <antihong at tt.co.kr>... Message is too
    large; 5024000 bytes max
    554 5.0.0 <antihong at tt.co.kr>... Service
    unavailable
    와 같은 에러 메시지를 회신받게 된다. 

    아울러
    # maximum number of recipients per SMTP envelope
    O MaxRecipientsPerMessage=20

    와 같은 부분이 있는데, 이 부분은 한번에 메일 발송 시 동시 발송(참조 발송)
    이 가능한 메일 계정의 수를 뜻하는 것으로 SMTP 서비스를 제공한다면 이 설정
    을 적용하는 것이 좋다. 기본적으로 이 값에도 제한이 없으므로 먼저 주석을
    삭제한 후 적절한 값을 설정해 주면 한번에 동시 발송 가능한 메일의 수도 제
    한할 수 있다.
    (위의 경우에는 한번에 참조 발송이 가능한 메일 유저를 20명으로 제한)
    설정이 끝난 후에는 killall –HUP sendmail 로 sendmail 을 재가동해주면 적
    용된다.



    메일 용량 쿼터 설정하기

    각 유저의 홈페이지 공간에 대한 쿼터 설정방법은 잘 알고 있는데, Sendmail
    을 제공시 메일 용량 쿼터에 대한 설정은 잘 모르는 경우가 많이 있다. 매일
    쿼터에 대한 설정은 다소 복잡하기는 하지만 설정은 가능하다.  기본적으로
    각 유저의 메일은 /var/spool/mail/ 디렉토리에 자신의 계정 소유로 저장이 되
    게 되는데 바로 이 특성을 이용하여 쿼터 설정이을 하면 된다.   쿼터는 각 파
    일 시스템별로 각각 설정이 가능하므로 각 유저의 홈디렉토리외에 /var 파티션
    에도 추가적으로 쿼터를 설정하면 되는 것이다.
    쿼터를 설정하는 방법은 일반적인 방법과 동일하다.
    먼저 /etc/fstab 파일을  열어 /var 파티션이 별도로 설정되어 있다면 /var 파
    티션에,  별도로 없으면 / 파티션에 유저쿼터나 또는 그룹쿼터 설정을 하면 된
    다.

    /dev/sda1             /home       ext2    defaults,usrquota=/home/.quota
    /dev/sda8             /var         ext2   
    defaults,usrquota=/var/.mailquota

    위에서는 /home 파티션에도 쿼터 설정을 하고 /var 파티션에도 쿼터 설정을
    한 것을 볼 수 있다.  이후 touch /home/.quota 및 touch /var/.mailquota 로
    사이즈가 0인 파일을 생성한 후  quotacheck –a 를 실행하면 파일 시스템을
    스캔하여  디스크 사용량을 체크하여 해당 파일에 정보를 저장한다.

    edquota user 를 실행하면

    /dev/sda1: blocks in use: 0, limits (soft = 99980, hard = 99980)
           inodes in use: 0, limits (soft = 0, hard = 0)
    /dev/sda8: blocks in use: 0, limits (soft = 29980, hard = 29980)
           inodes in use: 0, limits (soft = 0, hard = 0)

    위와 같이 쿼터 설정이 나오는데,  여기에서 /dev/sda1 은 /home/ 디렉토리에
    대한 쿼터 설정이고, /dev/sda8 은 /var/ 디렉토리에 대한 쿼터 설정이다. 위
    설정으로 각각 /home 디렉토리에는 100메가로, 메일 용량은 30메가로 총 130메
    가를 할당하여 쿼터를 설정한 것을 알 수 있다. 만약 별도의 /var 파티션이 없
    이 / 파티션만 있는 상황에서 100 메가로 쿼터 설정을 했다면 이 용량은 홈페
    이지의 용량과 메일 용량을 합쳐서 100메가로 적용이 되므로 주의하기 바란다.

    ##################### 참고.  Quota 의 설정에 대해
    위와 같이 edquota 사용시 관련된 라인이 아래와 같이 보이는 부분이 있다.
    이 중
    "blocks in use:" 는 유저가 현재 파티션에서 사용중인 총 블럭의 수를 킬로
    바이트로,
    "inodes in use:" 는 유저가 현재 파티션에서 사용중인 총 파일의 개수를 보
    여준다.
    이 두개의 "blocks in use:" 와 "inodes in use:" 는 시스템에 의해 자동으
    로 설정되고
    제어되므로 이 값을 임의로 변경할 필요는 없다.
    그리고 quota 설정시 soft 제한(soft = 5000)은 유저가 사용할 수 있는 최대
    용량을 뜻하며  (이 예제에서는 약 5M 이다.) hard 제한(hard = 6000)은 유저
    가 초과할 수 없는  절대적인 디스크 사용량을 뜻한다.  "hard limit"
    는 "grace period" 옵션이 설정되었을 때에만 적용된다.
    grace period 는 쿼터가 설정된 유저나 그룹이 soft limit 을 초과한 이후에
    도 사용 가능한 시간의 한계이다. 예를 들어서 여러분이 관리하는 시스템
    에 "해당 유저의 홈디렉토리를 50MB 로 쿼터 제한하고  초과시 7일간의 유예기
    간을 준다"는 정책을 세울 수도 있다. 각자 유예 기간의 설정에 대해서는 나름
    대로 적당하다고 생각하는 기간을 정의할 수 있다. grace period 는
    edquota –t 로  확인 및 설정할 수 있으며 아래의 경우에는 grace period 가
    7일로 설정되어 있는 것을 알 수 있다.

    /dev/sd1: block grace period: 7 days, file grace period: 7 days
    /dev/sda8: block grace period: 7 days, file grace period: 7 days

    그리고 한 유저에게 적용된 쿼터 설정을 다른 유저에게도 그대로 적용하려
    면 –p 옵션을 사용하면 되는데, 아래와 같이 실행하면 edquota 프로그램
    은 /etc/passwd 에 정의된 유저중 UID 가 499 이후의 모든 유저에 대
    해 "user" 의 쿼터 설정을 그대로 복사하게 된다.

    edquota -p user `awk -F: '$3 > 499 {print $1}' /etc/passwd`

    ####################################################################


    만약 쿼터가 초과된 계정에 메일을 발송하게 되면 아래와 같은 에러 메시지가
    나며 더 이상 메일을 수신하지 못하게 된다.







    sendmail 이 정상적으로 작동하는지 여부를 아는 방법

    sendmail 이  현재 작동중인지 확인하는 방법은 아래 두 가지 방법으로 가능하
    다.

    (1) # ps auxw|grep sendmail 로 확인
    위와 같이 확인시 
    root      0.0  0.0  2684 1460         S    Aug24 sendmail: accepting
    connections on port 25

    와 같이 sendmail: accepting connections on port 25 로 보이면 정상적으로
    작동하는 것이다. 만약 sendmail 이 다운되어 작동하지 않을 때는 sendmail:
    rejecting connections 라는 메시지가 보이게 된다.

    (2) sendmail 이 반응하는 25번 포트로 접속.

    # telnet tt.co.kr 25
    Trying 211.47.66.50...
    Connected to tt.co.kr.
    Escape character is '^]'.
    220 www10.tt.co.kr ESMTP Today and Tomorrow (http://tt.co.kr/)

    와 같이 sendmail 이 바인딩하는 25번 포트로 telnet 을 접속하면 sendmail
    이 반응을 하게 되는데, 위와 같이 접속을 하여 응답이 있을 경우에는 접속을
    받아들일 준비가 되어 있는 상태이며 반응하지 않을 때는
    Trying  tt.co.kr...
    telnet: Unable to connect to remote host: Connection refused
    와 같이 접근이 거부되었다는 것을 알 수 있다.


    갑자기 sendmail 이 작동하지 않을 때

    sendmail 이 작동하지 않는 경우는 주로 2가지이다.

    첫번째는, 시스템의 부하율인 Load Average 가 높아져 sendmail 이 작동하지
    않는 경우이고 두번째는 sendmail 에서 받는 메일이 저장되는 /var 파티션이
    100%가 되었을 경우이다.
    Sendmail 은 기본적으로 시스템의 Load Average 수치가 12를 초과하였을 경우
    에는 자동으로 작동하지 않게 되는데 이는 sendmail이 서비스 거부 공격등으
    로 시스템의 부하가 높아졌을 때 sendmail 로 인하여 시스템이 다운되는 것을
    막기 위한 조처이다.
    이 값을 수정하려면 sendmail.cf의
    # load average at which we refuse connections
    O RefuseLA=12
    에서 수정한 후 killall –HUP sendmail 로 재실행해 주면 되고, 이 값은 각각
    의 시스템에 따라 적절히 조정하면 된다.  만약 현 시스템의 특성상 늘 부하
    가 높아 로드가 자주 12를 초과한다면 이 값을 각자의 시스템 환경에 맞게 적
    절히 조절하여야 외부에서 오는 메일을 받을 수 있게 된다.(서버에서 25번 포
    트로 바인딩하고 있어야 외부에서 오는 메일을 수신할 수 있다.) 그리고 메일
    이 저장되는 /var/spool/mail 파티션이 가득 찼을 경우(파티션 100%) 에도
    sendmail 이 작동하지 않으므로 파티션이 가득 찼을 경우에는 /var/log/ 등에
    서 불필요한 데이터를 삭제하여 /var/spool/mail 이 포함된 파티션이 100% 를
    넘지 않도록 하여야 한다. 용량 정리를 하여 파티션이 100%가 넘지 않으면
    sendmail 이 자동으로 살아나는 것을 알 수 있다.
    또한 시스템의 Load Average 가 8을 넘으면 서버를 통해 메일을 발송해도 메일
    을 통해 바로 전송되지 않고 일단 서버의 메일 큐에 저장이 된 후에 발송이 되
    게 된다. 이 역시 같은 이유 때문인데 이 수치는 sendmail.cf 의

    # load average at which we just queue messages
    O QueueLA=8
    에서 적절히 설정하면 된다.

    참고로 현재 시스템의 Load Average는 w 명령어를 이용하여 확인 가능하다.
    w 를 이용시 시스템의 Load Average 는 0.25, 0.40, 0.43  와 같이 보이는데
    이는 각각 현재를 기준으로 지난 1분, 5분, 15분간의 평균 시스템 부하율을 나
    타낸다.



    sendmail 애서 보내는 메일(SMTP) 기능을 차단하고자 할 때

    sendmail 에서 Relay 기능을 막아 두었다 하더라도 최근 버전에는 사용자 인증
    (SMTP AUTH) 기능이 있어 서버에 계정이 있으면 모든 유저가 메일 서버를 이용
    해 SMTP 기능을 이용하여 메일을 발송할 수 있다. 이를 막으려면 최신의
    8.11.4 나 8.11.5 와 같이 최신 버전으로 업그레이드 후 /etc/mail/smtpauth
    파일에 보내는 메일  기능을 허용할 유저를 입력해 주면 된다. (최근에
    8.11.6 이전 버전에 심각한 보안 문제가 확인되었으므로 반드시 8.11.6 버전이
    나 8.12 버전으로 업그레이드하여야 한다.)  파일을 생성 후 아무런 유저도 입
    력하지 않으면 서버에 계정이 있다 하더라도 어느 누구도 메일을 발송할 수 없
    게 된다. 따라서 최신의 8.11.6 버전으로 업그레이드 할 것을 권장한다. 이외
    여러 변형된 방법이 존재하는데, ipchains 나 iptables 를 이용해 패킷 필터링
    을 하는 방법도 있다.

    커널 2.2.X 일 경우
    ipchains -A output -p tcp -y -d 0/0 25 -j DENY
    커널 2.4.X 일 경우
    iptables -A OUTPUT -p tcp --syn --dport 25 -j DROP

    위와 같이 설정시 목적지(Target) 포트가 25번 포트로 향하는 초기화(SYN) 패
    킷만을 차단하여 메일을 발송할 수 없도록 한다. 물론 초기화(SYN) 패킷에 대
    해서만 필터링을 하였으므로 외부에서 오는 메일을 받는 것은 관계 없다.

    바이러스 메일 필터링 방법

    최근에 Sircam 이나 Nimda 등 일정 주기마다 발생하는 바이러스 메일 때문에
    서버 관리자들은 마음 고생이 이만저만이 아니다. Sendmail 에서는 이러한 바
    이러스 메일이나 스팸메일에 대해 룰셋(ruleset)을 이용하여 차단하는 기능이
    있는데, 이를 사용하는 방법에 대해 알아보도록 하자.
    Sendmail 에서는 제목이나 메일러 또는 첨부파일의 화일명등 각종 메일헤더 정
    보를 이용하여 필터링을 할 수 있는데, 먼저 발송되는 메일 제목(subject)으
    로 필터링을 해 보도록 하자. 아래는 메일 제목에 ILOVEYOU 로 발송하는 멜리
    사 바이러스를 차단하는 룰셋을 적용해 본 예이다.

    먼저 sendmail.cf 파일을 열어 제일 하단에 아래의 내용을 추가한다.

    HSubject: $>Check_Subject
    D{WORMmsg}Access Denied - This message may contain a virus.

    SCheck_Subject
    RILOVEYOU               $#error $: 501 ${WORMmsg}
    RRe: ILOVEYOU           $#error $: 501 ${WORMmsg}
    RFW: ILOVEYOU           $#error $: 501 ${WORMmsg}

    # 주의 :  $#error 앞의 blank는 스페이스가 아니라 반드시 탭으로 띄워주어
    야 한다.
    Sendmail.cf 의 설정 내용이 다소 어렵고 복잡하기는 한데, 위 설정의 의미를
    간단히
    살펴보도록 하자.

    H -- 위 경우에는 헤더에서 Subject:라는 문자열을 찾아 이 헤더를
    Check_Subject로 정의한다.
    D -- WORMmsg 라는 매크로를 정의하여 해당 룰셋에 적용되는 제목을 확인시 발
    송한
       유저에게 보낼 메시지를 정의한다.
    S -- 헤더에서 check_subject로 정의한 부분을 룰셋으로 지정하는 부분이다.
    R -- 해당 문자열이 포함된 메일을 발견시 앞에서 정의한 에러 메세지를 첨부
    하여
        반송을 시킨다.

    위와 같이 룰셋을 적용하였을 경우 "I LOVE YOU" 와 같이 공란이 있을 경우 적
    용되지 않으며 "ILOVEYOU from me" 와 같이 특정 단어가 추가시에도 적용되지
    않으며 반드시
    정확히 일치하여야 한다. 추가적으로 회신시 추가되는 Re: 와 전달(포워딩)시
    추가되는 FW: 가 추가된 메일도 거부한다.

    다음으로 얼마전 유행했던 Sircam 바이러스 메일을 필터링해 보도록 하자.
    Sircam 바이러스의 헤더를 보면 정상적인 메일과는 달리 메일 헤더에
    Content-Disposition: Multipart message 와 같은 부분이 추가되어 있으며 이
    특징을 이용하여 필터링을 하면 된다.

    Sendmail.cf 파일에 아래의 룰셋을 추가하면 된다.

    HContent-Disposition: $>check_sircam
    D{SIRCAM}"Warning: I  Guess Sircam.worm Virus"
    Scheck_sircam
    RMultipart message      $#error $: 550 ${SIRCAM}

    # 주의 :  $#error 앞의 blank는 스페이스가 아니라 탭으로 띄워주어야 한다.

    sendmail.cf의 수정을 끝낸 후 바로 sendmail을 재 시작하지 말고
    룰셋이 정상적으로 작동하고 있는지 아래와 같이 테스트를 하는 것이 좋다.

    # /usr/lib/sendmail –bt                 # 테스트 모드로 접속
    ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
    Enter 
    > check_sircam Multipart message        # Sircam 룰셋 테스트
    check_sircam       input: Multipart message
    check_sircam     returns: $# error $: 550 553 Warning: I  Guess
    Sircam.worm Virus
    > ctrl-D                                # 테스트 종료

    위와 같이 확인된 후 sendmail을 재시작(killall –HUP sendmail) 하면 바로
    적용된다.
    아래와 같이 tail –f  /var/log/maillog 로 로그 파일을 지켜보면 아래와 같
    이 실제로 Sircam 바이러스가  필터링되고 있음을 확인할 수 있다.

    Sep  27 15:09:51 www sendmail[21386]: f8369of21386:
    to=<antihong at tt.co.kr>, delay=00:00:01,
    pri=241584 Warning: I  Guess
    Sircam.worm Virus.

    마지막으로 최근에 가장 영향을 많이 주었던 변형된 Nimda Worm 을 필터링하
    는 방법에 대해 알아보자. Nimda Worm 은 정상적인 메일 메시지와 달리 헤더에
    boundary="====_ABC1234567890DEF_===="       나
    boundary="====_ABC123456j7890DEF_===="      라는 부분이 있는데, 이 부분으
    로 필터링을 할 수 있다. 즉 메일 헤더에 위와 같은 설정이 되어 있으면 
    Nimda Worm 으로 간주하고 필터링 하면 되는 것이다. Sircam 에서와 같은 방법
    으로 sendmail.cf 파일의 설정은 아래와 같다.

    HContent-Type: $>check_ct

    D{NIMDA}"I guess NIMDA.WORM!!!"

    Scheck_ct
    R$+boundary="====_ABC1234567890DEF_===="       $#error $: 550 ${NIMDA}
    R$+boundary="====_ABC123456j7890DEF_===="       $#error $: 550 ${NIMDA}

    이외 메일 필터링에 대한 더욱 구체적인 방법에 대해서는 
    http://certcc.or.kr/paper/tr2001/tr2001-03/email security by
    procmail.html 나
    http://quanta.khu.ac.kr/~dacapo/sendmail/rulesets/ 를 참고하기 바란다.
    그리고 이외 관련하여 바이러스를 스캔하거나 필터링 할 수 있는 몇몇 프로그
    램이 있는데 이에 대해서는 http://www.rav.ro/ , http://www.amavis.org/ ,
    http://www.sophos.com/ 등을 참고하기 바란다.


    메일이 받아지지 않는 경우

    아웃룩 익스프레스에서 “배달” 을 눌러 메일을 수신하려고 할 때 메일이 받
    아지지 않는  경우가 있다. 이러한 경우에는 아래와 같이 여러가지 이유가 있
    을 수 있으니 아래의 사항에 대해 하나씩 원인을 찾아보기 바란다.
    (1) IMAP 패키지가 설치되지 않았을 경우
    서버에 배달되어 있는 자신의 계정으로 온 메일을 클라이언트 PC에서 받으려
    면 pop3 데몬이 반응하게 된다.  pop3d 는 IMAP 패키지안에 포함되어 있으므
    로, IMAP 패키지를 설치하여야 pop3 를 사용할 수 있다. Rpm 으로 설치했다면
    rpm –q imap 으로 현재 시스템에 imap 패키지가 설치되어 있는지 확인한다.
    또는 /usr/sbin/ipop3d 파일이 있는지 확인해 본다.
    (2) Inetd 에 설정되어 있지 않을 경우
    pop3d 는 inetd 또는 Xinetd 에서 작동하게 된다.
    /etc/inetd.conf 또는 /etc/xinetd.conf 파일을 살펴보아 ipop3 가 주석처리
    되어 있거나 pop3 가 disable =  yes 로 되어 있지는 않은지 확인한다.
    (3) TCP Wrapper 에 설정되었는지 여부 확인
    /etc./hosts.deny 에 pop3d 접근이 차단되지는 않았는지 확인한다.
    (4) 계정에 Lock 이 걸리지 않았는지 확인
    메일을 받는 과정에서 갑자기 회선이 끊기거나 PC가 다운되는 등 비정상적으
    로 종료시 서버의 pop3d 프로세스가 죽지 않고 계속 남아 있는 경우가 있다.
    이러한 경우 계정에 “Lock 이 걸렸다” 라고 하며 이러한 경우에는 해당 프로
    세스를 찾아 kill 을 하면 된다. 만약 계정에 Lock 이 걸린 상태에서 아웃룩
    익스프레스에서 메일을 수신하려고 하면 아래와 같은 에러가 나게 된다.
    “메일 서버에 로그온하는 데 문제가 있습니다. 지정한 암호가 거부되었습니
    다.
    계정: 'temazone.com', 서버: 'tt.co.kr', 프로토콜: POP3, 서버 응답:
    '-ERR Can't get lock.  Mailbox in use', 포트: 110, 보안(SSL): 아니오,
    서버 오류: 0x800CCC90, 오류 번호: 0x800CCC92”

    (5) Pop3 접속이 많은 경우
    Pop3d 가 서비스되는 inetd는 기본적으로 60초동안 40회의 접속을 받아들이
    도록 (즉, maximum 40회 fork되도록) 설정되어 있다. 따라서 짧은 시간에
    pop3d
    요구가 많을 경우에는 메일로그에 pop3/tcp server failing (looping) 라는 메
    시지가
    나면서 pop3d 데몬 자체가 다운되어 버리므로 동시에 처리 가능한 프로세스의
    한계
    를 적절히 높여주어야 한다.
    이를 위해서는 /etc/inetd.conf 를 열어 아래와 같이 수정하면 된다.

    이전설정)
    pop-3    stream    tcp    nowait    root     /usr/sbin/tcpd    ipop3d

    변경 설정)
    pop-3    stream    tcp    nowait.200    root    /usr/sbin/tcpd    
    ipop3d
    (위의 경우 처리 가능한 프로세스를 200회로 늘려주었다.)
    이후 killall -HUP inetd 를 하면 된다.

    (6) 110 번 포트로 확인
    아래와 같이 pop3d 포트인 110번 포트로 직접 접속하여 수작업으로 확인 가능
    하다.

    # telnet  pop3.tt.co.kr 110           # 110번으로 직접 확인
    Trying 210.17.6.5...
    Connected to pop3.tt.co.kr.
    Escape character is '^]'.
    +OK POP3 pop3.tt.co.kr v2001.76 server ready
    user abc                              # abc 라는 계정으로 접속
    +OK User name accepted, password please
    pass xyz                              # abc 의 암호 xyz 입력
    +OK Mailbox open, 10 messages
    quit                                  # 접속을 끊음.
    +OK Sayonara
    Connection closed by foreign host.

    위의 경우는 정상적인 경우이며 에러가 있을 경우(만약 암호가 다르게 설정되
    었을 경우 -ERR Bad login 와 같은 메시지가 나게 된다.) 각각의 경우에 따라
    에러 메시지를
    각각 확인할 수 있다.

    (7) mail –v 로 확인
    타 서버에서 mail –v antihong at tt.co.kr 와 같이
    메일을 발송하여 정상적으
    로 메일이 도착하는지를 확인해 본다. –v 옵션을 이용하여 메일 발송시에는
    메일 전송의 경로 및 메일 서버간에 주고받는 메시지를 확인할 수 있으므로 문
    제의 원인을 찾는데 도움이 된다.



    특정한 곳으로만 메일이 돌아올 때

    다른 곳은 문제가 없는데, 해외등 특정한 곳으로만 메일이 전송되지 않고 리턴
    되는 경우가 있다. 이러한 경우라면 자신의 메일서버가 mail-abuse.org 의 블
    랙 리스트에 등록되어 있지는 않은지 확인해 볼 필요가 있다. 특히 회신된 메
    일에 “...refused by blackhole site relays.mail-abuse.org” 와 같은 메시
    지가 보인다면 반드시 여부를 확인해 보아야 한다. 적지 않은 메일 서버에서
    는 메일 수신시 실시간으로 이 데이터를 참조하므로 mail-abuse.org 에서 스
    팸 메일 서버로 등록되면 이 기관에 등록된 도메인으로 메일을 보낼 때 받는
    쪽에서는 스팸 메일로 간주하고 수신을 거부하게 된다. 이를 확인하는 방법은
    http://mail-abuse.org/cgi-bin/nph-rss 사이트에서
    메일 서버의 IP 를 조회
    해 보면 된다.  아래는 위 사이트에서 한 IP 에 대해 조회해 본 결과 블랙 리
    스트에 등록되어 있는 것을 보여주고 있다. 이러한 경우라면 조회한 메일 서버
    의 Relay 가 허용되어 스팸 메일 서버로 사용된 적이 있거나 현재 사용되고 있
    다는 뜻이다.  만약 스팸메일 서버로 등록되어 있지 않다면 211.47.65.xxx is
    NOT currently on the RSS list 와 같이 보이게 된다. 






    자신의 메일 서버를 이 블랙리스트에서 제외하려면 먼저 자신의 메일서버에
    Relay 가 허용되어 있는지 확인 후 메일 서버에서 Relay 를 거부 설정한 후 
    If you'd like 211.47.65.135 to be removed from our list, please click
    here. 를 따라 클릭하여 신청을 하면 된다. 이 링크를 클릭하면 신청폼이 나오
    는데, 이 곳에 입력하여 신청을 하면 바로 처리가 된다. Relay 거부 설정을
    한 후 신청을 해야 처리가 되므로 반드시 사전에 Relay 거부 설정을 확인하기
    바란다. 메일 서버의 Relay 여부를 조회하는 방법에 대해서는 본지 10월호
    “철벽 보안을 위한 모니터링 올가이드” 를 참고하기 바란다.


    복수 MX 설정시 주의해야 할 점 

    DNS 서버에서 설정하는 MX 레코드는 해당 호스트로 수신되는 편지를 다른 호스
    트로 라우팅 하도록 한다. 특히 웹서버와 메일 서버를 분리하고자 할 경우 사
    용되는데, 원격 호스트에서 아래와 같이 설정된 도메인 tt.co.kr 로 편지를 송
    신할 경우에 Sendmail이 어떻게 동작하는지 알아보자.


    tt.co.kr.         IN   MX    10     mail1.tt.co.kr.
                   IN   MX     20    mail2.tt.co.kr.
                   IN   MX     20    mail3.tt.co.kr.

    다음은 메일이 수신되는 차례를 보여준다.

    (1) Preference 값이 10으로 가장 낮은 mail1 로 먼저 배달을 시도한다.
    (2) 만약 mail1.tt.co.kr 이 접근이 불가능하면 mail2 혹은 mail3 으로 배달
    을 시도한다.
    (3) (2) 에서 시도한 메일서버로도 접근이 되지 않으면 (2)에서 접근 되지 않
    은 호스트로
      배달을 시도한다. 즉 mail2 로 전송을 시도했다면 mail3 으로 배달을 시도
    한다.
    (4) mail2 와 mail3 서버에 접근이 불가능하다면 자체 큐잉 후, 일정 기간동
    안 주기적으로      
       1-3의 과정을 반복한다.

    흔히 MX 레코드에 대해 잘못 생각하는 것 중 하나는 만약  mail1 이 다운되어
    mail2 로 편지가 배달되었을 때, 편지가 mail2 의 메일 박스에 저장 된다고 생
    각하는 것이다. 만약  이렇게 된다면 유저 입장에서는 메일 수신시 pop3 서버
    를 mail1.tt.co.kr 와 mail2.tt.co.kr 과 같이 여러 개 설정해야 하는 것처럼
    보인다. 그러나 일반적으로 mail2.tt.co.kr 이나 mail3.tt.co.kr 처럼
    Preference 가 높은(즉 우선도가 낮은) 값을 갖는 메일 서버는 큐잉 서버로 동
    작하도록 설정하기 때문에, 결국 메일은 하나의 호스트(mail1)로 모이게 되는
    것이다. 위와 같이 mail2와 mail3 서버가 큐잉 메일 서버로 작동하려면 mail1
    와 mail2의 sendmail 이 아래와 같이 설정되어야 한다.

    (1) 해당 도메인(tt.co.kr)에 대한 인증을 갖지 않아야 한다.
    (즉, mail2 나 mail3 메일 서버의 sendmail.cw 또는 local-host-names 파일에
    tt.co.kr 이 설정되어 있으면 안 된다.)

    (2 )서버는 해당 호스트로의 메일 릴레이(Relay)를 허용하여야 한다.
    (즉, /etc/mail/access 에서 아래와 같이 정의되어야 한다.)
    mail1.tt.co.kr    relay

    인증을 갖지 않아야 한다는 것은 Sendmail의 w 클래스(sendmail.cw(local-
    host-names)  혹은 sendmail.cf의 Cw)에 tt.co.kr 도메인이 설정되지 않아야
    하는 것을 의미하고, 메일 릴레이란 수신되는 편지의 최종 배달지가 자신이 아
    닐 경우, 즉 인증을 갖지 않을 경우 편지를 해당 호스트로 포워딩하는 것을 의
    미한다.  최근의 배포판에서는 기본적으로 sendmail이 릴레이를 거부하도록 설
    정되어 있으므로 메일 큐잉 서버의 경우는 해당 호스트를 목적지로 하는 메일
    에 대해서는 릴레이를 허용하도록 설정하여야 한다는 것을 주의하기 바란다.
    mail1 의 다운으로 인해 mail2 로 전달되는 메일은 메일큐에 저장되어 있으면
    서, 일정 기간(Sendmail.cf에서 지정된 Timeout.queuereturn=5d 만큼)동안 주
    기적(Sendmail 구동시 지정된, 일반적으로 30분 -q30m)으로 mail1 로 배달이
    재시도된다.


    메일 서버의 버전을 숨기는 법

    다른 데몬도 마찬가지이지만 메일 서버 역시 해당 포트로 원격 접속을 해  보
    면 메일 서버의 버전 정보등을 확인할 수  있다. 그러나 시스템 관리자 입장에
    서 보안상의 문제로 현재 운영중인 메일 서버의 버전등을 숨기거나 속이고 싶
    을 때가 있는데. 이러한 경우에는 아래의 방법을 이용하면 된다.

    (1) sendmail 의 경우
      sendmail.cf 파일을 보면 아래와 같은 설정이 있다.
    # SMTP initial login message (old $e macro)
    O SmtpGreetingMessage=$j Sendmail $v/$Z; $b
    이 부분을 적절히 삭제하거나 다른 정보로 입력후 sendmail 을 재가동하면 된
    다.
    필자가 운영하는 메일서버의 경우
    O SmtpGreetingMessage=$j Today and Tomorrow(http://tt.co.kr/) 와 같이

    정하였고 이때 25번 포트로 접속시 보이는 정보는 아래와 같다.

    # telnet tt.co.kr 25
    Trying 211.47.66.50...
    Connected to tt.co.kr.
    Escape character is '^]'.
    220 www10.tt.co.kr ESMTP Today and Tomorrow(http://tt.co.kr/)

    (2) pop3d 의 경우
    pop3d 의 경우 소스에서 직접 수정하여야 하는데, 압축 해제한 디렉토리
    의 /src/ipopd 에 보면 ipop3d.c 파일이 있다. 이 파일을 살펴보면 

    char *version = "2001.75";   /* server version */
    라는 부분이 있는데,  필자가 운영하는 pop3d 의 경우 소스에서
    char *version = "xxxxxxxxxx";   /* server version */
    와 같이 수정 후 컴파일 하였고 이때 110번 포트로 원격 접속시 보이는 정보
    는 아래와 같다.

    # telnet tt.co.kr 110
    Trying 211.47.66.50...
    Connected to tt.co.kr.
    Escape character is '^]'.
    +OK POP3 www10.tt.co.kr vxxxxxxxxxx server ready

    버전외 다른 각종 정보도 수정할 수 있으니 각자 상황에 맞게 적절히 설정하
    기 바란다.


    sendmail 과 관련된 몇 가지 명령어

    >> mail1q
    mailq 프로그램의 목적은 큐잉된(/var/spool/mqueue 에 저장된) mail 메시지
    의 요약된 정보를 보여준다.  네트워크 다운등 어떤 특정한 이유로 바로 발송
    되지 못한 메일은 일차적으로 /var/spool/mqueue 에 큐잉된 상태로 저장된 후
    일정 시간마다 발송을 위해 재시도가 되는데,  현재 큐잉된 메일 메시지의 요
    약 정보를 보려면 아래와 같이 확인할 수 있다.

    # mailq

    /var/spool/mqueue/q1 (2 requests)
    ----Q-ID---- --Size-- -----Q-Time----- ------------Sender/Recipient------
    ------
    f7A84oV15068     1446 Fri Aug 10 17:04 nobody
                    (Deferred: Connection timed out with kebi.net.)
                                          darling at kebi.net
    f775ieF24893   521898 Tue Aug  7 14:44 <shlee at
    tt.co.kr
    >
                    (Deferred: Connection timed out with mail.unitel.net.)
                                          <cf1318 at
    unitel.net
    >
    /var/spool/mqueue/q2 is empty
                   /var/spool/mqueue/q3 (1 request)
    ----Q-ID---- --Size-- -----Q-Time----- ------------Sender/Recipient------
    ------
    f775nJF25249   230815 Tue Aug  7 14:49 <shlee at
    tt.co.kr
    >
                    (Deferred: Connection timed out with hanmail.com)
    cuwww23 at hanmail.com

    위 메시지를 보면 어떠한 이유로 메일이 발송되지 못하고 있는지를 추측할 수
    있다.
    3 메시지 모두 수신자의 e-mail 주소를 잘못 기입했기 때문인데, 각각
    kebi.com 인데, kebi.net 으로 unitel.co.kr 인데, unitel.net 으로 ,
    hanmail.net 인데, hanmail.com 으로 도메인 주소를 잘못 기입하여 메일을 발
    송하여 서버에서 메일을 발송하지 못하고 큐에 저장되어 있는 것을 확인할 수
    있다.
    여기에서 주의할 점은 mailq 명령어는 일반 유저로 실행하여 확인이 가능하므
    로 퍼미션을 700 등으로 조절하여 일반 유저들은 실행할 수 없도록 하는 것이
    좋다.

    >> mailstats
    mailstats 프로그램은 현재의 메일 송수신과 관련하여 통계를 보여준다.

      * 현재의 메일 통게를 보려면 아래와 같이 확인할 수 있다.

    # mailstats
    Statistics from Sat Aug 11 04:02:02 2001
    M   msgsfr  bytes_from   msgsto    bytes_to  msgsrej msgsdis  Mailer
    1        0          0K        3        317K        0       0  *file*
    4      690     596691K      824     137070K    68426       0  esmtp
    9       63      12212K        0          0K       27       0  local
    =============================================================
    T      753     608903K      827     137387K    68453       0
    C      753                  827                68453

    이를 적절히 이용하면 mrtg 를 이용해 일정 시간마다 발송되고 수신되는 메일
    의 개수를 통계로 내어 그래프로 볼 수 있다.(본지 10월호, 철벽보안을 위한
    모니터링 올가이드 참조)

    최근 sendmail 관련 버그에 대해

    한동안 문제가 없었던 sendmail 에 최근 들어 몇 가지 보안 문제가 발견되었
    다.
    이 버그는 매우 치명적인 문제인데, 아직 이를 모르고 그대로 사용중인 유저들
    이 많은 것 같다. 각자의 메일 서버에는 해당사항이 없는지 꼭 확인해 보기 바
    란다.

    첫번째로, 8월말에 발표된 버그는 현재 대부분의 메일 서버 프로그램으로 사용
    중인 sendmail 8.11.6 이전 버전에 해당하는 보안버그로서 일반유저가 Local
    에서 root 권한을 얻을 수 있는 매우 치명적인 버그인데, 이미 공격 소스가 여
    러 사이트에 공개되어 있다.
    참고로 이 버그는 8.11.0부터 8.11.5 버전까지만 해당하므로 8.10.x 나 8.9.x
    는 해당되지 않는다.  따라서 아래의 사이트를 참고로 sendmail 을 8.11.6 이
    나 8.12등 최신버전으로 업그레이드하기 바란다.

    8.11.0부터 8.11.5 의 경우 8.11.6 으로 업그레이드하면 되고 8.12.0.Beta 의
    경우 8.12.0.Beta19 이상으로 업그레이드하면 된다. 이에 대해서는
    http://www.securityfocus.com/bid/3163
    http://www.sendmail.org/8.11.html
    를 참고하기 바란다.

    두번째는, 10월초에 발견된 버그로서  모든 버전에 해당하는 문제인데, 이전에
    도 자주 나왔던 문제이다. 바로 shell 접근이 가능한 일반유저가 sendmail
    에 -q 옵션을 사용하여 큐에 있는 메시지를 드롭할 수 있는 문제이다. 아래의
    설명을 보기 바란다.

    [user@net user]$ id
    uid=778(user) gid=778(user)
    [user@net user]$ mailq
                   Mail Queue (1 request)
    --Q-ID-- --Size-- -----Q-Time----- ------------Sender/Recipient----------
    --
    NAA05248       11 Tue Oct  2 13:03 user1
                    (Deferred: Connection refused by tt.co.kr.)
                                      test at tt.co.kr

    [system@net system]$ /usr/sbin/sendmail -q -h10000
    Too many hops 10000 (25 max): from system via localhost, to test
    at tt.co.kr

    Too many hops 10000 (25 max): from MAILER-DAEMON via localhost, to
    postmaster
    Too many hops 10000 (25 max): from MAILER-DAEMON via localhost, to
    postmaster
    MAILER-DAEMON... Saved message in /usr/tmp/dead.letter
    [user@net user]$ mailq
    Mail queue is empty

    위와 같이 hop count 를 크게 설정함으로써 일반 유저가 현재 큐의 내용을 강
    제적으로 drop 시킬 수 있다.

    세번째는 역시 모든 버전에 해당하는 문제로 일반 유저가 sendmail -q -d0-
    xxxx.xxx 와 같이 사용시 (xxx는 디버깅 레벨이다.) 일반 유저가 메일서버의
    각종 설정 뿐만 아니라 큐에 저장되어 있는 내용, 메시지 경로나 제목, 메일
    소프트웨어등의 정보를 볼 수 있는 문제이다.
    두번째,세번째 문제는 sendmail.cf 에서

    O PrivacyOptions=authwarnings,novrfy,noexpn,restrictqrun
    와 같이 restrictqrun 를 추가함으로써 해결 가능하다.


    기타 메일과 관련된 장애가 확인 시

    지난달 아파치 웹서버의 장애에 대해 이야기하면서 문제나 장애가 발생시에는
    웹서버의 error_log  메시지를 살펴보도록 이야기 했었다.  메일서버도 마찬가
    지이다. 메일서버 장애시는 문제의 원인을 찾기 위해 로그 파일을 살펴보는 습
    관을 들이는 것이 좋다.
    메일 관련 로그는 /var/log/messages 나 /var/log/maillog 파일을 살펴보면 되
    며 로그파일을 보면 여기에서 언급하지 않은 문제가 발생했다 하더리도 어렵
    지 않게 원인을 찾을 수 있을 것이다.   다시 한번 강조하지만 모든 문제의 원
    인과 해결책은 로그에 있다는 것을 명심하기 바란다.
    2006/09/08 23:28 2006/09/08 23:28
    이 글에는 트랙백을 보낼 수 없습니다
    출처 블로그 > 도시의 매연 위 푸른하늘...
    원본 http://blog.naver.com/savemyface/120006480613
    1. 로케일(Locale)의 의미
    세계 여러 나라들은 각자 다른 문화(언어, 날짜, 시간 등)을 갖고 있다. 프로그램의국제화(Internationalization, 줄여서 i18n)는 사용자로 하여금 프로그램 수행시 로케일이란 것에 의해 입맛에 맞는 환경을 선택할 수 있도록 만든 것을 말한다. 예를 들어 어떤 프로그램의 메시지가 여러가지 언어로 주어져 있는 경우 이중에 어떤 언어의 것을 출력할 것인가를 사용자가 결정할 수 있는 것이다. 그것을 가능하게 해 주는 수단이 바로 로케일이다. 이것은 단순히 메시지 뿐만이 아니고 숫자표현법, 날짜 또는 시간표현법 등 여러가지에 사용될 수 있다. 그것 각각을우리는 카테고리(category)라고 부른다. 카테고리에는 LC_COLLATE, LC_CTYPE, LC_MESSAGES, LC_MONETARY, LC_NUMERIC, LC_TIME 가 있다.
    2. 로케일 설정방법
    로케일을 지원하는 프로그램의 실행 방식을 선택하기 위해서는 환경 변수 설정을 이용한다. (카테고리 각각에 해당하는 환경변수는 카테고리 이름과 동일하다.)
    로케일 환경 변수에 관한 정보는 locale이란 명령으로 간단히 얻을 수 있다.

    % locale
    LANG=ko_KR.eucKR
    LC_CTYPE="ko_KR.eucKR"
    LC_NUMERIC="ko_KR.eucKR"
    LC_TIME="ko_KR.eucKR"
    LC_COLLATE="ko_KR.eucKR"
    LC_MONETARY="ko_KR.eucKR"
    LC_MESSAGES="ko_KR.eucKR"
    LC_ALL=
    위에서 ko_KR.eucKR은 로케일 값(locale name)이다. 일반적인 로케일 값의 형식은 ll[_CC[.EEEE]][@dddd] 이다. ll은 언어(language)를 지정하는 소문자 두 글자 ISO 639 language code, CC는 지역(territory)를 지정하는 대문자 두 글자 ISO 3166 country code, EEEE는 코드셋(codeset)을 지정하는 문자셋(character set) 또는 인코딩(encoding), dddd는 방언 등의 변종을 구별하기 위한 것(modifier)이다. []로 표시된 내용은 안 쓸수도 있음을 의미한다. 예를 들면 en_US는 미국 영어권, en_CA는 영어권 카나다, de_DE는 독일의 독일어, fr_FR는 프랑스의 프랑스어를 의미한다.
    아무 로케일도 설정하지 않았을 때 glibc에서의 기본 로케일은 C 또는 POSIX (glibc에서는 C 로케일의 alias) 로케일이다.

    % locale -a
    라는 명령을 이용하면 이외에 사용 가능한 로케일의 이름들을 알 수 있다. 다음은 여러가지 환경변수의 역할(카테고리의 경우에는 동시에 카테고리의 역할)에 관한 설명이다.
    ☞ LANG : 모든 카테고리에 대한 로케일 설정을 위한 환경변수이다. 하지만 LC_* 환경변수보다 우선 순위가 낮다. LC_ALL이 설정이 안 되어 있고 LC_* 값들이 설정이 따로 설정이 않된 경우 LANG을 변화시키면 LC_ALL을 제외한 로케일 카테고리들의 값이 변경되지만 LC_ALL이 설정 되어 있는 경우 LANG의 변화는 로케일 카테고리들의 값에 영향을 주지 않는다.
    ☞ LC_CTYPE : 문자 분류(알파벳, 숫자, 한글 또는 소문자, 대문자 등등), 변환, 대소문자 비교을 위한 로케일 설정을 의미한다. 이것은 예를 들어 fgetwc(), is*(), isw*(), mblen(), mbtowc(), wcstombs() 등의 함수에 영향을 줄 수 있다.
    ☞ LC_COLLATE : 스트링(string)의 정렬 순서(sort order 또는 collation)를 위한 로케일 설정을 위해 사용된다. 이것은 예를 들어 strcoll(), wcscoll(), strxfrm() 등의 함수에 영향을 줄 수 있다.
    ☞ LC_MESSAGES : 메시지 표현을 위한 로케일 설정. 메시지의 국제화를 위한 catopen(), gettext() 등의 함수에 영향을 줄 수 있다.
    ☞ LC_NUMERIC : 금액이 아닌 숫자 표현(천단위, 소수점, 숫자 그룹핑 등)을 위한 로케일 설정. 예를 들어 strtod(), atof(). 
    ☞ LC_MONETARY : 금액 표현(천단위 구분 문자, 소수점 문자, 금액 표시 문자, 그 위치 등)을 위한 로케일 설정. 예를 들어 strfmon().
    ☞ LC_TIME : 시간과 날짜의 표현(년, 월, 일에 대한 명칭 등)을 위한 로케일 설정 예를 들어 strftime(), strptime().
    ☞ LC_ALL : 모든 카테고리에 대한 로케일 설정을 위한 환경변수이다. 위의 LC_* 및 LANG의 어떤 것보다 우선 순위가 높다. 그리고 LC_ALL을 설정하면 다른 로케일 카테고리의 값들이 LC_ALL의 값의 변경되고 LC_ALL설정을 없애면 다른 로케일 카테고리의 값들은 이전값을 유지한다.
    ☞ LANGUAGE : 로케일의 다중 설정을 위해 gettext에서 사용되는 GNU extension 환경변수로 LC_ALL보다도 우선순위가 높다. 로케일들은 구분문자 : 을 이용하여 우선순위가 높은 순대로 나열된다. 예를 들어 LANGUAGE=en_US:ko_KR
    ☞ LINGUAS : gettext를 사용하는 프로그램 설치시 지정한 언어들의 메시지만을 설치하기 위한 환경변수. 구분 문자는 스페이스이다. 예를 들어 LINGUAS="ko ja"
    로케일을 지원하기 위한 방법 및
    3. 작동 원리
    로케일을 제대로 지원하는 프로그램을 작성하기 위해서는 setlocale()함수를 이용하여 로케일을 설정하고 확인하여야 한다. setlocale()함수는 헤더 파일 locale.h 에 정의되어 있으며 그 프로토타입은 다음과 같다.
    char *setlocale (int category, const char *locale);
    이 함수의 역할은 카테고리 category에 대해 로케일 locale을 설정하고 (물론, 사용 가능한 로케일인 경우), 설정된 로케일값을 리턴하는 것이다.
    locale 부분에 ""을 넣은 다음과 같은 예는
    setlocale (LC_ALL, "");
    적당한 환경변수를 참조하여 로케일을 설정하고 그 값을 리턴한다. 환경변수를 참조하는 우선순위는 위에서 설명한대로 LC_ALL, 그외 카테고리, LANG변수 순이고, 변수값을 알아내면 locale.alias(예를 들어, /usr/share/locale/)를 참조한 후 뒤에서부터 @ . _ 을 단위로 순서대로 잘라가며 사용가능한 로케일을 찾아낸다.
    인수 locale 부분에 NULL을 넣은 다음예는
    locale = setlocale (LC_ALL, NULL);
    로케일 값을 변경시키지 않고 단지 카테고리에 관한 현재 로케일값을 알아내고자 하기 위해 그 리턴값을 사용하는 예이다.
    다음은 함수 setlocale()을 사용하여 임시로 로케일로 변경하는 예이다. (glibc manual에 있는 예)
        #include <stddef.h>
        #include <locale.h>
        #include <stdlib.h>
        #include <string.h>
       
        void
        with_other_locale (char *new_locale,
                           void (*subroutine) (int),
                           int argument)
        {
          char *old_locale, *saved_locale;
       
          /* 현재 로케일명을 알아낸다. */
          old_locale = setlocale (LC_ALL, NULL);
       
          /* setlocale()의 재호출 의해 변경될 것을 대비해 로케일 이름을 미리 복사해 둔다. */
          saved_locale = strdup (old_locale);
          if (saved_locale == NULL)
            fatal ("Out of memory");
       
          /* 로케일을 변경하고 subroutine을 수행한다. */
          setlocale (LC_ALL, new_locale);
          (*subroutine) (argument);
       
          /* 원래의 로케일로 복귀한다. */
          setlocale (LC_ALL, saved_locale);
          free (saved_locale);
        }

    다음은 로케일을 이용하여 날짜/시간을 출력하는 프로그램의 예이다.
    #include <stdio.h>
    #include <locale.h>
    #include <time.h>

    int main(void)
    {
    time_t now;
    struct tm *l_time;
    char string[256];

    /* 환경변수로부터 시간 관련 로케일을 결정한다. */
    setlocale(LC_TIME, "");

    /* calendar 시간을 now라는 변수에 저장.
    * 그 값은 1970년 1월 1일 이후부터 지금까지의 초단위 시간 */
    now = time((time_t *)NULL);

    /* calendar 시간의 다른 유용한 형태를 l_time변수에 저장 */
    l_time = localtime(&now);

    /* 우리가 원하는 포맷의 시간 포맷을 string이라는 변수에 저장 */
    strftime(string, sizeof string, "%c", l_time);

    /* 출력 */
    printf("%s\n", string);

    return 0;
    }
    다음은 위의 파일을 time_test.c라고 저장하고 컴파일하여 c쉘에서 시험하는
    예이다.
    % gcc -o time_test time_test.c
    % setenv LANG ko_KR.eucKR
    % ./time_test
    2000년 01월 12일 수요일 오후 10시 26분 56초
    % setenv LANG C
    % ./time_test
    Wed Jan 12 22:27:22 2000
    2006/09/08 23:28 2006/09/08 23:28
    이 글에는 트랙백을 보낼 수 없습니다
    출처 블로그 > 무일물(無一物)」
    원본 http://blog.naver.com/fr22m1n/140003752561

    이 글은 KELP의 조형기님 글을 가져와서 수정한 것입니다.

    - 들어가기 -
    리눅스를 잘 알지 못할 당시 나는 리눅스에는 왜 Visual C++가 없는지에 대해 불평하였다. 그런 편리한 IDE환경이 없는지에 대해서 참으로 불만이었다. 어쩔 수 없이 이상한 에디터 vi를 배우기 시작했고, 명령 라인에서 gcc 를 구동하기 시작했었다. 그러다 명령 라인에서 gcc 를 계속 두들기니까... 뭐 편한 거 없나 ? 하고 살펴보고, 즉시 make 를 공부했다. 지금까지 이런 과정을 거치면서 리눅스의 전통적인 아니 유닉스의 전통적인 개발 환경과 개발 방법이 아주 매력적이라는 사실을 알게 되었다.
    사실 알고 보면 Visual C++의 느낌표를 누르면 이러한 과정이 내부에서 일어나는 것이다. 우리 눈 앞에 안 보일 뿐이다. 나는 이 사실을 깨달았을때 Visual C++/MFC에 정이 뚝 떨어졌다. 지금도 어쩔 수 없는 초보이지만, 그러기에 나름대로 유닉스의 개발환경에 대하여 알아 본다.

    - 개요도 -
    이번에는 리눅스의 개발 환경이 전체적으로 어떻게 구성되어 있나 살펴보는 것이다. 우선 분류를 하여 나열해 보겠다.

    [1] GNU Toolkit
      1) Binutils
      2) GCC
      3) GDB
      4) C, C++ library

    [2] 디버깅 도구
      1) GDB
      2) DDD
      3) kdbg
      4) ldd
      5) strace
      6) ltrace
      7) checker

    [3] 시간측정, 성능평가도구
      1) time
      2) gprof
      3) calls

    [4] 자동 컴파일링 도구
      1) make
      2) m4
      3) Automake
      4) Autoconf

    [5] 인터페이스 만들기 도구
      1) Xt
      2) Motif/Lesstif
      3) Xaw3D
      4) Tcl/Tk
      5) QT
      6) GTK+

    [6] 버전 관리 도구
      1) CVS
      2) RCS
      3) SCCS

    [7] 파일 패치 & 들여쓰기
      1) patch
      2) diff
      3) indent

    한눈에 들어오니까 참 좋다. 이것을 보고 있으면 마음이 편안해진다. 빠진 내용이 있으면 피드 백을 해 주기 바란다. 여기에 나열되어 있는 모든 것들을 어느 정도 안다면 글쎄 유닉스/리눅스 초보는 분명 아닐 것이다. 위에서 [1] 항목은 분류항목으로 있기에 좀 그렇지만 대표적이라서 그냥 넣어 두었다.

    - 본론 -
    그럼 이제 하나하나 항목에 대해서 대충 알아보자. 이 내용들은 필자의 기반 지시과 '러닝 리눅스' 라는 책을 참고하였다. 이 책을 지은 '메트 웰시'라는 작자는 보통 사람은 아닌 것 같다. (www.linuxdoc.org 의 핵심 관리자이다.)

     [1] GNU toolkit
      1) Binutils - 여기에는 어셈블러(as), 링커(ld) 를 비롯하여 많은 바이너리 도구들이 포함되어 있다.
       ld - GNU 링커.
       as - GNU 어셈블러. ( 임베디드 리눅스를 하면서 어셈블리어는 필수겠죠?)
       addr2line - 주소를 파일명과 라인 수로 변경.
       ar - 정적 라이브러리를 만드는 유틸리티. (예 $ ar rs libxxx.a a.o b.o s옵션을 넣으면 ranlib 를 실행하지 않아도 된다.)
       c++filt - Filter to demangle encoded C++ symbols.
       gprof - 프로파일 정보 출력(프로파일러)
       nlmconv - 오브젝트 코드를 NLM으로 변경
       nm - 오브젝트 파일의 심볼들을 나열.
       objcopy - 오브젝트 파일을 복사 및 변환
       objdump - 오브젝트 파일을 덤프하여 여러가지 정보를 보여줌. 어셈블리어도 보여줌
       ranlib - 정정 라이브러리를 만들고 나서 인덱스 파일을 라이브러리 처음에 생성 시켜줌
       readelf - ELF 포맷의 오브젝트 파일의 정보 출력
       size - 오브젝트 또는 문서 파일의 정보 출력, text , data , bss, dec 등의 섹션 크기를 출력 (예 $ size any_program)
       strings - 파일로부터 출력 가능한 스트링 나열
       strip - 심볼 제거, 프로그램의 사이즈를 조금이라도 줄일려고 임베디드에선 많이 사용.
       windres - 윈도우즈용 파일을 위한 컴파일러
        ** 이런 바이너리 유틸리티를 능숙하게 다루는 것이 임베디드 리눅스 프로그래머에겐 필수이다.
        ** 그래서 나도 시간나는 데로 틈틈히,열심히 매뉴얼들을 읽고 있다. 시스템 프로그래밍의 기본이다.
      2) GCC - gcc에 대한 안내를 보라.
      3) GDB - 나는 명령라인에서 디버깅하는 프로그램. DDD라는 프로그램도 있다.
      4) c, c++ library - glibc 가 표준 C언어 라이브러이다.
       현재 나의 리눅스 머신에는 /lib/libc-2.2.2.so 라는 공유라이브러리로 존재한다.
       c++ 표준 라이브러리는 /usr/lib/libstdc++-3-libc6.2-2-2.10.0.so 라는 공유라이브러리로 존재한다.
       c library는 시스템 유틸리티들이 다 사용하기 때문에, c++ library 는 그렇지 않으니까, /usr/lib에 존재한다.
       물론 위의 두 개다 /usr/lib에 정적 라이브러리들로도 다 있다.
       표준 라이브러리의 소스는 www.gnu.org의 GNU Software 란에 다 있다.

     [2] 디버깅 도구
      1) gdb - 진짜 디버깅 툴
      2) ddd - GDB의 윈도우용 프론트 엔드
      3) kdbg - GDB의 윈도우용 프론트 엔드
       막강한 기능들을 많이 가지고 있다. 위의 프로그램 중에서는 ddd를 가장 많이 사용하는 것 같다.
       kdbg는 kde기반에서 나온것 같은데, kdevelop이라는 QT용 IDE툴의 기본 디버거로 들어가 있다.
      4) ldd - 공유 라이브러리 의존성을 출력해 준다. 불필요한 라이브러리는 제거하는 것이 좋다.
      5) strace / ltrace - 뭔가 추적하는 것이다.
       strace는 사용하는 시스템 콜을 추적하여 주는 것이고,
       ltrace는 라이브러리 호출을 추적하여 주는 것이다.
       지금 당장, hello world c언어 소스를 컴파일하여 실행하여 보라.
       그리고 strace/ltrace 를 실행하고 유심히 살펴보라. 감이 올 것이다!
        $ strace ./hello
       $ ltrace ./hello

      6) checker - 프로그램 코딩중 메모리 할당 루틴에서 문제가 있는 것 같으면, 사용하는 것이다.
       컴파일하기 전에 -lchecker 라는 옵션을 주는 것을 잊지 말자.
       그리면 문제가 있는 메모리 할당 루틴을 checker 가 검사하여 원인을 보고 하여 줄 것이다.

     [3] 시간 측정, 성능 평가 도구
      1) time - 프로그램의 수행 시간을 측정해 준다. 시스템 유틸리티이지만, 같은 이름의 라이브러리 함수가 있다.(man 2 time)
      2) gprof - 바이너리 유틸리티에 포함되어 있다. 이것은 프로파일러이다.
       즉, 코드 안에서 병목 현상을 일으키는 곳을 파악할 수 있다.
       각 함수가 얼마나 자주 호출되는지, 각 함수에서 소요된 시간 등 실행한 프로그램의 목록을 보여주는 도구이다.
       컴파일 할때 -pg 옵션을 주고 해야 한다. 컴파일 후 실행하라.
       정상적으로 종료하면, 현재 디렉토리에 gmon.out 이라는 파일을 내어 놓는다.
       이 파일안에 실행 프로파일 정보가 들어 있으며 gprof를 사용하여 통계값을 볼 수 있다.
        $ gprof 프로그램명 gmon.out
      3) calls - c 소스 코드 안에서의 호출 관계를 계층 구조로 보여 준다.
       호출된 모든 함수의 인덱스를 만들거나 프로그램 구조에 대한 계층 구조 보고서를 작성할 때 좋다.
        $ calls hello.c

     [4] 자동 컴파일링 도구
      1) make - 조금이라도 덩치 있는 프로그램을 작성해 보았다면 필요성을 절실히 느낄 것이다.
       make를 사용할 줄 모른다면, 남이 작성한 파일을 보고 수정할 수 있으면 된다.
       그러다 보면 자신만의 makefile을 만들수 있을 것이다.
      2) m4 / automake / autoconf - 플랫폼에 독립적인 프로그램을 배포할 때 필요한 것들이다.
       make 파일을 작성하는 것이 또 지루한 작업이기 때문에 그것을 자동으로 해주는 툴이 automake이다.
       autoconf는 configure 라는 스크립트를 자동으로 작성해 주는 툴이다.
       우리가 프로그램을 설치할때 리눅스에서, 가장 먼저, ./configre 하지 않는가?
       그 configure 스트립트를 만들어 주는 것이 autoconf 이다.
       configure 라는 스트립트는 여러가지를 시스템에서 찾아보고, 알맞은 makefile을 만들어 주는 것이다.
       그후에 make 명령을 이용해서 컴파일을 시키는 것이다.
       m4는 매크로 프리 프로세서라는 것이다. aotoconf에서 내부적으로 사용하는 것이다.

     [5] 인터페이스 만들기 도구
      1) Xt - X library의 기본 툴킷이다.
      2) Motif / Lesstif - 유닉스상에서 전통적으로 인기있는 윈도우 툴킷이지만 상용이다.
       오픈소스의 다음 세대(QT, GTK+)들에게 대세를 빼았기었다. 그리고 Lesstif 가 나왔지만 대세는 홀러간 뒤었다.
      3) Xaw3D - 표준 아데나(Athena)위젯의 변형 버전으로써 마치 모티프와 같은 스타일의 3D 효과를 준다.
      4) Tcl/Tk - 창, 버튼, 스크롤바 등 기존의 프로그램에서 사용하고 있는 X 기반의 완전한 인터페이스를 만들 수 있다.
      5) Qt - 트롤 테크(Troll Tech)가 만든 C++ GUI 툴킷이다.
       나는 QT로 윈도우 프로그래밍을 즐긴다. 왜냐면, 예쁘기 때문이다. 나는 뭐니뭐니 해도 예쁜게 좋다.
       gtk기반의 어플리케이션은 알고리즘이나 성능을 좋더라도, 보기에 좋지는 않다.
      6) GTK+ - 원래 김프라는 이미지 처리 프로그램을 위해 만든 C GUI 툴킷이다.

     [6] 버전 관리 도구
      1) CVS - (Concurrent Versioning system) 거의 표준으로 자리 잡고 있다. 인터넷으로 전세계 개발자들이
       함께 개발할 수 있게끔 해주는 멋진 도구이다. 거의 모든 오픈 소스 프로젝트들이 CVS로 개발되고 있다.
      2) RCS - (Revision control system) CVS와 비슷하다. RCS로는 한 그룹내에서 개발할때 사용한다.
      3) SCCS - (Source Code Control System) 카네기 멜론 대학에서 개발된 것이다.

     [7] 파일 패치 & 들여 쓰기
      1) patch - 정기적으로 갱신되는 프로그램이 있고 프로그램이 매우 많은 소스 파일로 이루어져 있으며
       한 버전에서 다음 버전으로 갱신하려고 상황에 맞게 파일을 변환시켜주는 프로그램이다.
       매번 전체 소스 배포 파일을 내놓는 것이 적절치 않을 때에 주로 사용한다.
       방법은 각 버전마다 변경된 부분만을 patch로 갱신하는 것이다.
      2) diff - patch보다 작은 규모의 업그레이드에 유용하게 사용된다.

      <사용법>
        $ patch -pNUM〈 patchfile
       $ diff [option] from-file to-file


      < 예제1. 소스가 단순 파일 하나일 때 >
      hello1.c 가 있고, 다음 버전인 hello2.c 가 있다고 하자.
      우선 hello.patch 라는 패치 파일을 만들어 내려면 다음과 같이 한다.
        $ diff -c hello1.c hello2.c > hello.patch
      이렇게 만든 패치 파일을 배포하며, 이 패치 파일을 다운 받은 사용자는 다음과 같이 하여 hello1.c 소스에 패치를 가한다.
        $ patch〈 hello.patch

      < 예제2. 소스가 디렉토리 구조일 때 >
      hello1 라는 디렉토리가 있고, 다음 버전인 hello2라는 디렉토리가 있다고 하자.
      우선 hello.patch 라는 패치 파일을 만들기 위해서는 다음과 같이 한다.
        $ diff -cr hello1 hello2 > hello.patch ( 옵션 -r 은 recursive를 의미 )
      이렇게 만든 패치 파일을 배포하며, 이 패치 파일을 다운 받은 사용자는 다음과 같이 hello1 디렉토리 구조에 패치를 가한다.
        $ patch -p0〈 hello.patch (-pNUM 에 대한 옵션은 맨페이지 참고)

      3) indent - 코드를 예쁘게 들여쓰기를 해준다. 다음과 같이 사용할 수 있다.
        $ indent hello.c

    출처 : 엠파스블로그 > 입으로 하는 행동, 손으로 하는 생각.

    > 테마 : Programming?

    2006/09/08 23:27 2006/09/08 23:27
    이 글에는 트랙백을 보낼 수 없습니다
    Linux/SHELL  2006/09/08 23:25
    grep 계열 명령어

    grep 명령어

    grep의 의미

    grep : 파일 전체를 뒤져 정규표현식에 대응하는 모든 행들을 출력한다.
    egrep : grep의 확장판으로, 추가 정규표현식 메타문자들을 지원한다.
    fgrep : fixed grep 이나 fast grep으로 불리며, 모든 문자를 문자 그래도 취급한다. 즉, 정         규표현식의 메타문자도 일반 문자로 취급한다.

    3.1.2 grep의 동작 방법

    grep에서 사용하는 정규표현식 메타문자
    메타문자
    기    능
    사용 예
    사용 예 설명
    ^
    행의 시작 지시자
    '^love'
    love로 시작하는 모든 행과 대응
    $
    행의 끝 지시자
    'love$'
    love로 끝나는 모든 행과 대응
    .
    하나의 문자와 대응
    'l..e'
    l 다음에 두 글자가 나오고 e로 끝나는 문자열을 포함하는 행과 대응
    *
    선행문자와 같은 문자의 0개 혹은 임의개수와 대응
    ' *love'
    0개 혹은 임의 개수의 공백 문자 후에 love로 끝나는 문자열을 포함한 행과 대응
    []
    [] 사이의 문자 집합중 하나와 대응
    '[Ll]ove'
    love나 Love를 포함하는 행과 대응
    [^ ]
    문자집합에 속하지 않는 한 문자와 대응
    '[^A-K]love'
    A와 K 사이의 범위에 포함되지 않는 한 문자와 ove가 붙어있는 문자열과 대응
    \<
    단어의 시작 지시자
    '\<love'
    love로 시작하는 단어를 포함하는 행과 대응(vi,grep에서 지원)
    \>
    단어의 끝 지시자
    'love\>'
    love로 끝나는 단어를 포함하는 행과 대응
    (vi,grep에서 지원)
    \(..\)
    다음 사용을 위해 태그를 붙인다.
    '\(lov\)ing'
    지정된 부분을 태크1에 저장한다. 나중에 태그값을 참고하려면 \1을 쓴다. 맨 왼쪽부터 시작해 태그를 9개가지 쓸 수 있다. 왼쪽 예에서는 lov가 레지스터1에 저장되고 나중에 \1로 참고할 수 있다.
    x\{m\}
    문자 x를 m번 반복한다.
    'o\{5\}'
    문자 o가 5회 연속적으로 나오는 모든 행과 대응
    x\{m,\}
    적어도 m번 반복한다.
    'o\{5,\}'
    문자 o가 최소한 5회 반복되는 모든 행과 대응
    x\{m,n\}
    m회 이상 n회 이하 반복한다.
    o\{5,10\}'
    문자 o가 5회에서 10회 사이의 횟수로 연속적으로 나타나는 문자열과 대응

    grep의 옵션
    옵션
    동작 설명
    -b
    검색 결과의 각 행 앞에 검색된 위치의 블록 번호를 표시한다. 검색 내용이 디스크의 어디쯤 있는지 위치를 알아내는데 유용하다.
    -c
    검색 결과를 출력하는 대신, 찾아낸 행의 총수를 출력한다.
    -h
    파일 이름을 출력하지 않는다.
    -i
    대소문자를 구분 하지 않는다.(대문자와 소문자를 동일하게 취급).
    -l
    패턴이 존재하는 파일의 이름만 출력한다.(개행문자로 구분)
    -n
    파일 내에서 행 번호를 함께 출력한다.
    -s
    에러 메시지 외에는 출력하지 않는다. 종료상태를 검사할 때 유용하게 쓸 수 있다.
    -v
    패턴이 존재하지 않는 행만 출력한다.
    -w
    패턴 표현식을 하나의 단어로 취급하여 검색한다.

    # grep -n '^jack:' /etc/passwd
    (/etc/passwd 파일에서 jack을 찾는다. jack이 행의 맨 앞에 있으면 행 번호를 화면으로 출력한다.)

    3.1.3 grep과 종료 상태
    grep은 파일 검색의 성공 여부를 종료 상태값으로 되돌려준다.
    패턴을 찾으면 0, 패턴을 찾을 수 없으면 1, 팡리이 존재하지 않을 경우 2
    sed,a자 등은 검색의 성공 여부에 대한 종료 상태값을 반환하지 않는다. 다만 구문 에러가 있을 경우에만 에러를 보고한다.

    3.2 정규표현식을 사용하는 grep의 예제
    # grep NW datafile
    # grep NW d*
    (d로 시작하는 모든 파일에서 NW를 포함하는 모든 행을 찾는다.)
    # grep '^n' datafile
    (n으로 시작하는 모든 행을 출력한다.)
    # grep '4$' datafile
    (4로 끝나는 모든 행을 출력한다.)
    # grep TB Savage datafile
    (TB만 인자이고 Savage와 datafile은 파일 이름이다.)
    # grep 'TB Savage' datafile
    (TB Savage를 포함하는 모든 행을 출력한다.)
    # grep '5\.' datafile
    (숫자 5, 마침표, 임의의 한 문자가 순서대로 나타나는 문자열이 포함된 행을 출력한다.)
    # grep '\.5' datafile
    (.5가 나오는 모든 행을 출력한다.)
    # grep '^[we]' datafile
    (w나 e로 시작하는 모든 행을 출력한다.)
    # grep '[^0-9]' datafile
    (숫자가 아닌 문자를 하나라도 포함하는 모든 행을 출력한다.)
    # grep '[A-Z][A-Z] [A-Z]' datafile
    (대문자 2개와 공백 1개, 그리고 대문자 하나가 연이어 나오는 문자열이 포함된 행을 출력한다.)
    # grep 'ss* ' datafile
    (s가 한 번 나오고, 다시 s가 0번 또는 여러번 나온 후에 공백이 연이어 등장하는 문자열을 포함한 모든 행을 출력한다.)
    # grep '[a-z]\{9\}' datafile
    (소문자가 9번 이상 반복되는 문자열을 포함하는 모든 행을 출력한다.)
    # grep '\(3\)\.[0-9].*\1 *\1' datafile
    (숫자 3,마침표,임의의 한 숫자,임의 개수의 문자,숫자 3(태그),임의 개수의 탭 문자,숫자 3의 순서를 갖는 문자열이 포한된 모든 행을 출력한다.)
    # grep '\<north' datafile
    (north로 시작하는 단어가 포함된 모든 행을 출력한다.)
    # grep '\<north\>' datafile
    (north라는 단어가 포함된 모든 행을 출력한다.)
    # grep '\<[a-z].*n\>' datafile
    (소문자 하나로 시작하고, 이어서 임의 개수의 여러 문자가 나오며, n으로 끝나는 단어가 포함된 모든 행을 출력한다. 여기서 .*는 공백을 포함한 임의의 문자들을 의미한다.)

    3.3 grep에 옵션 사용
    # grep -n '^south' datafile
    (행번호를 함께 출력한다.)
    # grep -i 'pat' datafile
    (대소문자를 구별하지 않게 한다.)
    # grep -v 'Suan Chin' datafile
    (문자열 Suan Chin이 포함되지 않은 모든 행을 출력하게 한다. 이 옵션은 입력 파일에서 특정 내용의 입력을 삭제하는데 쓰인다.
    # grep -v 'Suan Chin' datafile > black
    # mv black datafile
    )
    # grep -l 'SE' *
    (패턴이 찾아진 파일의 행 번호 대신 단지 파일이름만 출력한다.)
    # grep -w 'north' datafile
    (패턴이 다른 단어의 일부가 아닌 하나의 단어가 되는 경우만 찾는다. northwest나 northeast 등의 단어가 아니라, north라는 단어가 포함된 행만 출력한다.)
    # grep -i "$LOGNAME" datafile
    (환경변수인 LOGNAME의 값을 가진 모든 행을 출력한다. 변수가 큰따옴표로 둘러싸여 있는 경우, 쉘은 변수의 값으로 치환한다. 작은따옴표로 둘러싸여 있으면 변수 치환이 일어나지 않고 그냥 $LOGNAME 이라는 문자로 출력된다.)

    3.4 egrep
    egrep(extended grep) : grep에서 제공하지 않는 확장된 정규표현식 메타문자를 지원  한다.
                                        grep와 동일한 명령행 옵션을 지원한다.
    egrep에서 지원하는 확장 메타문자
    메타문자
    기능
    사용 예
    사용 예 설명
    +
    선행문자와 같은 문자의 1개 혹은 임의 개수와 대응
    '[a-z]+ove'
    1개 이상의 소문자 뒤에 ove가 붙어있는 문자열과 대응. move,approve,love,behoove 등이 해당된다.
    ?
    선행문자와 같은 문자의0개 혹은 1개와 대응
    'lo?ve'
    l 다음에 0개의 문자 혹은 하나의 문자가 o가 나오는 문자열과 대응. love,lve 등이 해당된다.
    a|b
    a 혹은 b와 대응
    'love|hate'
    love 혹은 hate와 대응.
    ()
    정규표현식을 묶어준다
    'love(able|ly)'
    lovable 혹은 lovely와 대응.
    '(ov)+'
    ov가 한 번 이상 등장하는 문자열과 일치.

    3.4.1 egrep 예제
    # egrep 'NW|EA' datafile
    (NW나 EA가 포함된 행을 출력한다.)
    # egrep '3+' datafile
    (숫자 3이 한 번 이상 등장하는 행을 출력한다.)
    # egrep '2\.?[0-9]' datafile
    (숫자 2 다음에 마침표가 없거나 한 번 나오고, 다시 숫자가 오는 행을 출력한다.)
    # egrep ' (no)+' datafile
    (패턴 no가 한 번 이상 연속해서 나오는 행을 출력한다.)
    # egrep 'S(h|u)' datafile
    (문자 S 다음에 h나 u가 나오는 행을 출력한다.)
    # egrep 'Sh|u' datafile
    (패턴 Sh나 u를 포함한 행을 출력한다.)

    3.5 고정 grep 과 빠른 grep
    fgrep : grep 명령어와 동일하게 동작한다. 다만 정규표현식 메타문자들을 특별하게 취급하지
             않는다.
    # fgrep '[A-Z]****[0-9]..$5.00' file
    ([A-Z]****[0-9]..$5.00 이 포함된 행을 출력한다. 모든 문자들을 문자 자체로만
    2006/09/08 23:25 2006/09/08 23:25
    이 글에는 트랙백을 보낼 수 없습니다
    Linux/SHELL  2006/09/08 23:12
    출처 블로그 > 수진오빠 개그소매상
    원본 http://blog.naver.com/soojin001/140005615267
    - 본 쉘 프로그래밍 -

    2001년 1월 13일
    written by 허정수(wertyu@nownuri.net)

    1. 왜 쉘 프로그래밍을 배워야 하는가?
    이 글을 읽는 사람들 중에서는 왜 쉘 프로그래밍을 배워야 하는지 아는 사람도 있고, 모르는 사람도 있을 것이다. 21 세기, 리눅스를 사용하기도 많이 편리해지고, X 윈도를 실행해서 버튼 몇 개만 클릭하면 편하게 사용할 수 있는데 왜 어려운 쉘 프로그래밍을 배워야 하는지 모르는 사람도 있을 것이다.

    하지만, 리눅스를 어느 정도 사용해 본 사람이라면, 리눅스를 편하게 사용하기 위해서 쉘의 사용법과 쉘 프로그래밍을 꼭 알아야 하는 것을 알고 있을 것이다. 어느 책에서는 MS Windows와 유닉스/리눅스의 가장 큰 차이점을 바이너리와 텍스트로 설명하고 있다. 즉, MS Windows는 바이너리 유닉스는 텍스트이다. MS Windows는 모든 설정을 바이너리로 관리하여 사용자가 직접 프로그램의 설정을 변경할 수 없고, 설정을 변경하기 위해서는 꼭 설정을 변경하는 프로그램을 통해야만 한다.(regedit 처럼) 하지만 유닉스는 모든 설정을 텍스트 파일로 관리한다. (요즘 MS Windows도 Script를 이용하여 설정을 바꿀 수 있도록 변하고 있는 추세이다. 즉 유닉스의 장점을 MS Windows도 이해하고 따라가고 있다.)

    이 극명한 차이가 쉘 프로그래밍을 배워야 하는 이유이다. 예를 들어 설명해 보자. 시스템 교체를 위해 MS Windows와 유닉스의 사용자 1만 명을 다른 시스템으로 옮긴다고 생각해 보자. MS Windows에서는 분명 사용자 추가하는 프로그램을 실행하여 각 1만 명의 아이디와 암호 및 프로필을 손수 입력해야 할 것이다. 아무리 클릭을 빠르게 하고, 타이핑이 아무 빨라고 많은 시간이 필요하다. 하지만, 유닉스에서는 간단하게 스크립트를 짜서 실행하면 된다.

    다른 예도 있다. 다음과 같이 현재 디렉터리에 확장자가 gif인 파일이 많이 있다고 하자.

    13:28[wertyu@inos test]$ ls
    a.gif b.gif c.gif d.gif mmv.sh*

    그런데, 여기 있는 gif 파일의 확장자를 모두 jpg로 바꾸려고 한다. 앞의 예에서는 파일이 4개 밖에 안 되지만 만약, 파일이 1000개 라면 당신은 어떻게 할 것인가. 이 때 간단히 스크립트를 짜서 실행하면 쉽게 확장자를 고칠 수 있다. 다음의 스크립트는 확장자가 gif인 파일의 확장자를 jpg로 바꾸는 스크립트이다.(프롬프트 앞의 13:13은 필자의 프롬프트에서 시간을 나타낸다.)

    13:31[wertyu@inos test]$ cat mmv.sh
    #! /bin/sh

    X=`ls *.gif`
    for B in $X
    do
    temp=`basename $B .gif`
    mv $B $temp.jpg
    done

    13:31[wertyu@inos test]$ ls
    a.gif b.gif c.gif d.gif mmv.sh*
    13:31[wertyu@inos test]$ ./mmv.sh
    13:31[wertyu@inos test]$ ls
    a.jpg b.jpg c.jpg d.jpg mmv.sh*

    어떤가 쉽지 않은가?

    2. How the Shell Interpret What You Typed

    이번 절에서는 아주 간단히 쉘이 어떻게 작동하는지 알아 보려 한다. 이번 절의 제목을 해석해 보면, "쉘은 당신이 입력한 것을 어떻게 해석하는가"(How the Shell Interpret What You Typed)이다. 쉘이 작동하는 방법을 조금이나마 이해하기 바란다. 다들 알고 있겠지만, 쉘은 리눅스에서 명령을 내리는데 가장 중요한 프로그램이다.(MS Windows에서의 Shell은 Internet Explorer이다. 알고 있었나?). 쉘은 명령을 내리기 위해서는 어쩔 수 없이 거쳐야 하는 프로그램이기 때문에 쉘이 작동 원리를 이해하면 명령을 쉽고 빠르고 간단하게 입력할 수 있다. 또한 쉘이 작동하는 원리를 정확히 이해해야만 쉘 프로그램도 잘 짤 수 있다.

    다음의 예를 보자. 다음과 같이 간단한 C로 작성한 프로그램이 있다.

    13:42[wertyu@inos test]$ cat how.c
    #include <stdio.h>

    void main(int argc, char* argv[])
    {
    int cnt ;

    for( cnt = 1 ; cnt < argc ; ++cnt )
    {
    printf("arguement %d = %s
    ", cnt , argv[cnt] ) ;
    }
    }

    이 프로그램을 how라는 실행 파일로 컴파일 해 놓자.

    문제 1.
    다음의 실행 결과는 무었인가?

    $ how $HOME

    을 실행 시키면 출력 결과는 무었일까? 이 문제는 쉬울 것이다.

    답 1.

    13:47[wertyu@inos test]$ ./how $HOME
    arguement 1 = /home/wertyu
    13:47[wertyu@inos test]$

    문제 2.

    디렉터리에 다음과 같은 파일들이 있다.

    13:48[wertyu@inos test]$ ls
    a.jpg b.jpg c.jpg d.jpg how* how.c mmv.sh*

    다음을 실행하면 무엇이 출력 될까.

    13:48[wertyu@inos test]$ ./how *

    이건 조금 어렵다. 쉽게 맞출 수 있는 사람도 있겠지만, 대부분의 사람들은 '*'가 출력된다고 답할 것이다. 그러나 답은....

    답 2.

    13:48[wertyu@inos test]$ ./how *
    arguement 1 = a.jpg
    arguement 2 = b.jpg
    arguement 3 = c.jpg
    arguement 4 = d.jpg
    arguement 5 = how
    arguement 6 = how.c
    arguement 7 = mmv.sh
    13:49[wertyu@inos test]$

    위의 두 문제를 풀어 봄으로서 대충이나마 쉘의 작동 방법을 이해할 수 있었을 것이다.

    3. 쉘 스크립트를 작성해 보자.

    이제 기본적인 설명은 끝났으므로 실제 쉘 스크립트를 작성해 보자. 쉘 스크립트의 첫 줄은 항상 다음과 같이 시작을 해야 한다.

    #! /bin/sh

    이 첫 줄은 인터프리터를 지정하는 줄이다. 앞으로 나올 여러 명령들을 인터프리트할 프로그램을 지정한다. 마찬가지로 awk로 스크립트를 작성하기 위해서는 스크립트의 첫 줄은 #! /bin/awk로 시작해야 할 것이다.

    쉘 스크립트를 작성하는 방법은 간단한다. 사용하기 편한 에디터로 명령들을 적은 후에 파일의 모드를 '실행' 모드를 주는 것이다. 다음의 예를 보자


    14:01[wertyu@inos test]$ cat > echo.sh
    #! /bin/sh
    echo $1

    14:02[wertyu@inos test]$ chmod 775 echo.sh
    14:02[wertyu@inos test]$ ./echo.sh Parameter
    Parameter
    14:02[wertyu@inos test]$

    위의 예를 보면 알 수 있듯이 각자 사용하기 편리한 에디터로 스크립트를 작성한 후 chmod 명령으로 파일에 실행 권한을 주어 실행 할 수 있다. 참고로 앞에 나온 echo.sh은 입력받은 parameter 중 첫 번째 parameter를 출력하는 쉘 스크립트이다.

    3.1 변수의 선언 및 사용법

    쉘 프로그램에서 변수를 선언하는 방법을 알아 보자. 변수는 간단히

    변수명=변수값

    과 같이 선언할 수 있다. 여기서 중요한 것은 '변수명'과 '=', '변수값' 사이에 공백이 있으면 안 된다는 것이다. 따라서 다음과 같은 쉘 프로그램은 잘못된 것이다.

    14:07[wertyu@inos test]$ cat wrong.sh
    #! /bin/sh
    x = 123
    echo $x
    14:07[wertyu@inos test]$ ./wrong.sh
    ./wrong.sh: x: command not found

    'x = 123' 부분을 'x=123'과 같이 수정한 후 실행 시키면 123이 출력되는 것을 볼 수 있다.

    선언한 변수를 사용하기 위해서는 앞의 예와 같이 변수명 앞에 $를 붙여주면 된다.

    3.2 Flow of Control
    Flow of Control이란 한글 책에서 흔히 '흐름 제어'로 번역되는 단어로서 '조건 분기문' '루프' 등을 나타낸다. 어떠한 프로그램이든 그 프로그램을 구성하는 프로그램 logic 중 80%는 Flow of Control일 정도로 어떤 language를 배우든 Flow of Control을 익히는 것은 매우 중요하다.

    3.2.1 if 문

    본 쉘 프로그래밍에서 if문은 다음과 같이 사용된다.

    if test_statement_A
    then
    statement_B
    statement_C
    else
    statement_D
    fi

    다음의 예를 보자

    14:36[wertyu@inos test]$ cat test.sh
    #! /bin/sh

    if [ $# -eq 0 ]
    then
    echo "No arguement"
    else
    echo "There are $# arguement(s)"
    fi
    14:36[wertyu@inos test]$ ./test.sh
    No arguement
    14:36[wertyu@inos test]$ ./test.sh a b c d e
    There are 5 arguement(s)

    여기서도 중요한 것은 '[' 와 조건을 검사하는 부분과 ']' 사이에 공백이 있어서는 안 된다는 것이다.
    '$#' 변수는 본쉘 스크립트의 특수 변수로서 인자의 수를 나타내는 변수이고, -eq는 equal의 약자로서 두 수가 같은지 비교하는 연산자 이다.

    if [ $# -eq 0 ] 은 다음과 같이 바꾸어 사용해도 된다.

    if test $# -eq 0

    즉, 앞의 test.sh 스크립트는 다음의 스크립트와 동일하게 동작한다.

    14:42[wertyu@inos test]$ cat test.sh
    #! /bin/sh

    if test $# -eq 0
    then
    echo "No arguement"
    else
    echo "There are $# arguement(s)"
    fi

    test는 외부 명령으로서 주어진 expression을 검사하여 true or false를 return하는 명령이다. 여기서 test를 예로 든 것은 if 의 조건에는 외부 명령이 함께 쓰일 수 있기 때문이다. 즉, 다음 스크립트와 같이 작동하는 스크립트를 작성할 수 있다.

    if ls plot.ps
    then
    lpr plot.ps
    else
    echo ":::: ERROR FILE DOESN'T EXIST ::::"
    fi

    앞의 예제 스크립트는 plot.ps라는 파일이 있을 경우에 프린트를 하고, plot.ps라는 파일이 없을 경우에는 에러 메시지를 출력하는 스크립트이다.


    3.2.2 숫자의 비교

    앞의 예에서 -eq로 두 수의 값이 같은지 비교하는 것을 보았다. -eq 외에도 많은 연산자가 있다.

    -eq : equal, 두 수가 같냐?
    -ne : not equal, 두 수가 같지 않냐?
    -gt : greater than, 왼쪽 변수가 오른쪽 변수보다 크냐?
    -lt : less than, 왼쪽 변수가 오른쪽 변수보다 작냐?
    -ge : greater than or equal, 왼쪽 변수가 오른쪽 변수보다 크거나 같냐?
    -le : less than or equal, 왼쪽 변수가 오른쪽 변수보다 작거나 같냐?

    3.2.3 문자열의 비교

    문자열을 비교하기 위한 연산자는 다음과 같다.

    [ "String1" = "String2" ] : 두 문자열이 같은지
    [ "String1" != "String2" ] : 두 문자열이 다른지
    [ -z $X ] : $X라는 문자열 변수의 길이가 0이면 참
    [ -n $X ] : $X라는 문자열 변수의 길이가 0이 아닐 경우 참

    또한 '!'는 NOT을 나타낸다. 따라서 다음의 두 expression은 같은 것이다.

    [ -z $X ]
    [ ! -n $X ]

    3.2.4 File 검사

    이번 절에서는 File과 관련된 test를 알아보기로 한다. 파일이 존재하는지 검사하는 스크립트는 프로그램의 설정 파일을 검사할 때 많이 쓰인다. 예를 들어 $HOME/.vimrc가 있을 경우 $HOME/.vimrc 설정 파일을 읽어 들이고 없을 경우 default 설정 파일을 읽어 들이도록 하는데 사용될 수 있다.

    [ -b file ] : file이 존재하고 file이 block special file인 경우 참
    [ -c file ] : file이 존재하고 file이 character special file인 경우 참
    [ -d file ] : file이 존재하고 file이 directory인 경우 참
    [ -f file ] : file이 존재하고 file이 일반적인 file인 경우 참
    [ -g file ] : file이 존재하고 file에 Set-Group-Id가 set 되어 있는 경우 참
    [ -h file ] : file이 존재하고 file이 symbolic link인 경우 참
    [ -H file ] : file이 존재하고 file이 hidden directory인 경우 참
    [ -k file ] : file이 존재하고 file에 sticky bit가 set되어 있는 경우 참
    [ -p file ] : file이 존재하고 file이 named pipe인 경우 참
    [ -r file ] : file이 존재하고 file에 읽기 권한이 있는 경우 참
    [ -s file ] : file이 존재하고 file의 size가 0이 아닌 경우 참
    [ -u file ] : file이 존재하고 file에 Set-User-Id가 set되어 있는 경우 참
    [ -x file ] : file이 존재하고 file에 실행 권한이 있는 경우 참
    [ -w file ] : file이 존재하고 file에 쓰기 권한이 있는 경우 참

    위의 모든 것을 외울 필요는 없지만 쉘 스크립트에서 file과 관련하여 어떤 것을 검사할 수 있는지 정도는 알아두는 것이 좋다.

    3.2.5 AND/OR 연산자

    C 언어에서는 &&가 logical AND 연산자, ||가 logical OR 연산자인데, 본 쉘 프로그래밍에서는 AND는 -a, OR는 -o 이다.

    3.2.6 Loop

    본 쉘 프로그래밍에서는 C 언어와 비슷하게 3 개의 Loop 관련 문을 제공한다.

    3.2.6.1 for

    for문의 문법은 다음과 같다

    for VARIABLE in LIST
    do
    STATEMENT1
    STATEMENT2
    done

    1절에서 잠시 살펴 본 여러 file의 확장자를 동시에 바꾸는 스크립트를 다시 한 번 살펴보자

    #! /bin/sh

    X=`ls *.gif`
    for B in $X
    do
    temp=`basename $B .gif`
    mv $B $temp.jpg
    done

    X에 ls *.gif의 값이 저장된다. 이 값은 LIST의 형태로 생각하면 된다. 즉, 차례로 확장자가 gif인 파일이 저장된다고 생각하라.
    for B in $X를 살펴 보면, 앞의 ls *.gif의 결과 값 각각에 대해서 for 이하의 문을 실행하라는 것이 된다. 그리고 그 각각의 값은 임시로 B에 저장이 된다.

    temp=`basename $B .gif`

    basename은 $B에서 .gif 부분을 제외한 부분을 리턴하는 프로그램이다. 직접 프롬프트에서 명령을 내려서 결과를 확인할 수도 있다.

    23:17[wertyu@inos test]$ basename wertyu.gif .gif
    wertyu

    여기서 중요한 것은 '가 아니라 `이라는 점이다. 쉘 스크립트에서 변수의 값에 외부 명령을 실행 시킨 결과 값을 저장하기 위해서는 ` command `를 이용하면 된다. 즉

    temp=`basename $B .gif`

    는 $B에서 .gif 부분을 떼어버리고 남은 문자열을 temp에 저장하는 것이 된다. 나머지는 쉽게 이해할 수 있을 것이라 생각된다.

    다음의 스크립트는 grep과 비슷한 스크립트이다. (출처:http://pneuma.phys.ualberta.ca/~gingrich/research/shells/shells.html, 이 글에서 설명한 본 쉘 스크립트의 문법은 앞의 사이트에서 가져온 것도 몇 개 있으니 참고하기 바란다.)

    #! /bin/sh
    #
    # A script to look for the occurence of a string in a file
    # Usage: match [string] [file]
    #
    for word in `cat $2`
    do
    if [ ``$word'' = ``$1'' ]
    then
    echo ``Found $1 in file $2''
    else
    :
    fi
    done

    각자 이해해 보시길.... 근데, ``$word'' = ``$1'' 의 의미는 필자도 잘 모르겠다. 그냥 $word = $1으로 바꿔도 잘 돌아가던데....

    3.2.6.2 while

    for 문에 대해서는 이해가 되었을테니 이제 while 문을 볼까?

    문법)

    while condition
    do
    commands
    done

    예) 10, 9, 8,...,1을 출력하는 스크립트이다.

    number=10
    while [ $number -ge 1 ]
    do
    echo $number
    number=`expr $number - 1`
    done

    while은 condition이 참일 동안 loop를 돈다.

    3.2.6.3 until

    until은 while과 거의 비슷하다.

    문법)

    until condition
    do
    commands
    done

    단, while과 한 가지 차이점이 있는 것은 while은 condition이 참일 동안 loop를 돌지만, until은 condition이 거짓일 동안 loop를 돈다는 것이다.

    다음의 예는 while에서의 예와 같은 일을 하는 스크립트를 until을 이용하여 작성한 것이다.

    예)

    number=10
    until [ $number -lt 1 ]
    do
    echo $number
    number=`expr $number - 1`
    done

    3.2.7 case 문

    이 번 절에서는 case 문에 대해서 알아 보겠다. C 언의 case와 아주 유사하므로 쉽게 이해할 수 있을 것이다. 단, C 에서는 if-elseif를 쉽게 case 문으로 바꿀 수 있지만, 본 쉘 스크립트에서의 case는 if 보다 훨 씬 많은 기능을 제공한다.

    다음의 예를 보자.

    #!/bin/sh
    case $# in
    0)
    echo ""no parameters"";;
    1)
    echo "only one parameter." ;;
    *)
    echo "more than one parameter." ;;
    esac

    설명 안 해도 이제 이해되겟지? case 다음의 $#의 값에 따라서, 0)이냐 1)이냐에 따라서, 원하는 것을 실행 시킬 수 있다.
    위의 예에서는 case의 장점을 살펴 볼 수 없었다. 그러나 다음의 예를 보면, case의 유용함에 대해서 쉽게 알 수 있을 것이다. case의 유용함은 Regular Expression을 사용할 수 있다는 것이다. Regular Expression 까지 설명하려면 글이 길어 지므로, Regular Expression은 필자가 번역한 http://nnr.or.kr/linux/regular.htm을 참고하거나 다른 참고 자료를 살펴 보기 바란다.
    그럼 다음의 예를 보자

    while :
    do
    echo "Would you like to continue? c"
    read ANS
    case $ANS in
    [yY] | [yY][eE][sS]) echo "Fine, then we'll continue."
    break
    ;;
    [nN] | [nN][oO]) echo "We shall now stop."
    exit
    ;;
    *) echo "You must enter a yes or no verdict!"
    esac
    done
    echo "
    We are now out of the while loop."

    일단 저장해 놓고 실행 해 보자. 돌려 보면 알겠지만, Yes를 입력하든 Y를 입력하든 YES를 입력하든 yEs를 입력하든, [yY] | [yY][eE][sS])는 true가 된다.
    참 하나 설명을 안 하고 넘어간 부분이 있다.

    while :

    은 항상 참을 나타낸다.

    아. 또 read도 설명 안 했군. read ANS는 사용자로부터 문자열을 입력받아 ANS에 저장하는 명령이다.

    이 정도면 설명이 다 되었을 것이다.

    4. 마치면서

    아주 간단하게나마 본 쉘 프로그래밍에 대해서 알아 보았다. 너무나 간단하여 복잡한 일은 하기 힘들 것이다. 남은 것은 여러분의 노력 뿐... 아주 간단하게 본 쉘 스크립트를 알아 보았으므로, 다음 시간에는 TIP을 중심으로 본 쉘 스크립트에 대해서 알아 보겠다. 단, 필자도 아직 위의 내용 이외에는 아는 것이 별로 없으므로 공부를 한 후에 나머지 내용을 쓰도록 하겠다.

    * 참고 자료 :

    http://www.sao.nrc.ca/imsb/rcsg/documents/bourne/bourne.html
    http://pneuma.phys.ualberta.ca/~gingrich/research/shells/shells.html

    ps. 검색 엔진에서 shell programming이라고 입력하면 수 많은 결과가 나올테니 열심히 공부하기 바란다~~~


    -------------------------------------------------------------------------------------------


    출처 블로그 > Jay's
    원본 http://blog.naver.com/cocktail74/40004597832

    특수문자

    Match

    사용 예

    Match

    .

    임의의 한 문자

    *

    한 번도 없거나 한번 이상 반복

    abcd*

    abc, abcd, abcdd 등과 match

    .*

    모든 문자

    ^

    행의 처음

    ^X

    행의 첫머리의 X

    X^

    행의 임의의 위치의 X

    ^/^ or ^^

    행의 첫머리의 ^

    $

    행의 마지막

    X$

    행의 끝의 X

    $X

    행의 임의의 위치의 X

    \$$ or $$

    행의 끝의 $

    []

    [,] 안의 아무 문자

    c[aeiou]t

    cat, cet... 와 match

    -를 사용하여 범위 설정 가능

    c[a-z0-9]t

    두 번째 문자의 임의의 소문자나 숫자

    -와의 match를 위해선 [-나 -] 이용

    c[-ai]

    c-, ca, ci

    ]와의 match를 위해선 []와 같이 나타냄

    c[]ai]

    c], ca, ci

    ^를 [다음에 사용하면 [, ]안의 문자를 제외한 문자들과 match

    [A^-Z]

    대문자를 제외한 문자

    \{n,m\} (ed, sed, grep 에서만 사용 가능)

    \{n\}은 바로 앞의 expression이 n번 반복 된 것

    [0-9]\{3\}

    세 개의 숫자

    \{n,\}은 바로 앞의 expression이 n번 또는 그 이상 반복된 것

    0\{4,\}

    4개 이상의 0

    \{n,m\}는 바로 앞의 expression이 n번에서 m번 반복된 것

    1\{4,9\}

    4개에서 5개의 1

    \

    특수 문자들의 기능을 수행하지 않고 문자 그대로 받아들임

    \*\**

    한 개 또는 그 이상의 *

    ^[ ^I]*$

    공백행과 space나 TAB을 포함한 행(겉보기 공백행). 여기서 ^I는 ctrl+I로써 TAB과 같다

    ^.*$

    임의의 행 전체

    modifier를 이용하여 변수 값이나 history에 저장된 명령어의 내용을 변환시킬 수 있다.

    (단, set A = (/home/user/temp.c), set B = (a.c b.c c.c d.c))

    Modifier

    기능

    사용 예

    결과

    :h

    pathname에서 마지막 부분을 제어하고 앞부분만 남김

    echo $A:h

    /home/user

    :t

    pathname에서 마지막 부분만 남기고 pathname을 제거함

    echo $A:t

    temp.c

    :r

    pathname에서 끝 부분의 .xxx만 제거

    echo $A:r

    /home/user/temp

    :e

    .xxx만 남기고 앞부분 제거

    echo $A:e

    c

    :g

    :gh, :gr, :gt, :ge의 형태로 사용되며, array변수에 저장된 모든 값들에 h,r,t,e를 적용시킨다.

    echo $B:r

    a b c d

    :p

    명령어를 실행시키지 않고 출력만 시킨다.

    !:p

    :q

    특수 문자들의 기능을 수행하지 않고 단순히 출력만 시킨다.

    %echo *
    %!:q

    *

    특수문자

    의미

    비고

    !

    history 기능을 시작하기 위한 특수문자

    !n

    n번째로 사용된 명령 실행

    !-n

    현재부터 n번째 앞에 사용된 명령 실행

    !!

    바로 전에 실행되었던 명령 실행

    !-1

    !string

    가장 최근에 string으로 시작되는 명령 실행

    !?string[?]

    가장 최근에 string을 포함하고 있는 명령 실행

    ^aa^bb

    마지막으로 실행된 명령어에서 aa를 bb로 치환하여 명령 실행

    !*

    마지막으로 실행된 명령에 사용된 모든 argument

    !$ or !!$

    마지막 명령의 마지막 argument

    !^

    마지막 명령의 첫 argument

    event:s^aa^bb

    event는 앞에서 !로 시작하는 history 명령이다. aa를 bb로 치환한다. 단, ^대신 다른 특수 문자를 사용하여도 된다.

    ex) !23:s/aa/bb

    !:n or !!:n

    마지막 명령의 n번째 argument

    !:n*

    마지막 명령의 n번째부터 그 이후의 argument

    !:n-$

    !:0

    마지막 명령의 명령어만 나타냄

    !:n-m

    마지막 명령의 n번째부터 m번째까지의 argument

    !:-n

    마지막 명령의 명령어부터 n번째 argument까지

    !:n-

    마지막 명령의 n번째부터 마지막 argument를 제외한 argument

    !?string?%

    가장 최근에 string을 포함하고 있는 단어를 나타냄

    색코드

    의미

    0

    기본 화면색. 흰 글자색. 검정 배경색

    1

    bold intensity

    4

    흑백 모드에서는 밑줄

    5

    반짝임

    7

    역상

    30

    검정 (회색) 글자색

    31

    빨강 (옅은 빨강) 글자색

    32

    녹색 (옅은 녹색) 글자색

    33

    갈색 (노랑) 글자색

    34

    파랑 (옅은 파랑) 글자색

    35

    보라 (옅은 보라) 글자색

    36

    cyan (옅은 cyan) 글자색

    37

    흰색 (밝은 흰색) 글자색

    40

    검정 (회색) 배경색

    41

    빨강 (옅은 빨강) 배경색

    42

    녹색 (옅은 녹색) 배경색

    43

    갈색 (노랑) 배경색

    44

    파랑 (옅은 파랑) 배경색

    45

    보라 (옅은 보라) 배경색

    46

    cyan (옅은 cyan) 배경색

    47

    흰색 (밝은 흰색) 배경색

    10

    기본 font 선택

    38

    밑줄 사용 가능

    39

    밑줄 사용 불가능

    Escape Sequence

    기능

    ESCc

    화면을 지우고 커서를 1행 1열로 이동시킴

    ESC[nA

    커서를 현위치에서 위로 n칸 이동

    ESC[nB

    커서를 현위치에서 아래로 n칸 이동

    ESC[nC

    커서를 현위치에서 오른쪽으로 n칸 이동

    ESC[nD

    커서를 현위치에서 왼족으로 n칸 이동

    ESC[n;mH 또는 ESC[n;mf

    커서를 m열 n행으로 이동시킴

    ESC[nJ

    n = 0 이면 현위치에서 화면의 끝까지 지움
    n = 1 이면 화면의 처음에서 현위치까지 지움
    n = 2 이면 화면 전체를 지움

    ESC[nK

    n = 0 이면 현재 커서의 위치에서 행의 끝까지 지움
    n = 1 이면 행의 처음에서 현재의 커서 위치까지 지움
    n = 2 이면 현재 커서가 있는 행을 모두 지움

    ESC[nL

    n 행을 현재 커서 위치에 삽입

    ESC[nM

    현재 커서 위치에서부터 n행 삭제

    ESC[nP

    현재 커서 위치의 행의 처음부터 n개 문자 삭제

    ESC[nX

    현재 커서 위치에서부터 n개 문자 삭제

    ESC[nM

    화면의 색지정. 여러 가지 색을 지정할 때는 ;를 사용하여 구분한다.

    2006/09/08 23:12 2006/09/08 23:12
    이 글에는 트랙백을 보낼 수 없습니다
    출처 블로그 > 막강 파워 스킬만이 살길이다~
    원본 http://blog.naver.com/norther80/80010287760


    작성자 : 김칠봉
    작성일 : 2001.03.12

    목차
    1. 가장 일반적인 find 명령어

    2. find 명령어 일반적인 옵션
    2-1. 사용법 개요
    2-2. 일반적으로 표현식 옵션 구분
    3-3. 자주 사용되는 표현식 옵션
    3-4. path(find 명령어 다음의 path)
    3-5. 표현식-연산자

    3. 예제
    3-1. 다른 명령어와 결합형태(ls,xargs)
    3-2. 퍼미션 관련 예제
    3-3. 유저와 관련된 예제
    3-4. 팁
    - 최근 하루(1) 동안(-)에 변경(change)된 파일을 찾을려면(-ctime)?
    - 오래된 파일을 찾을려면(30일 이상 수정(modify))되지 않은)?
    - 최근 30일(30) 안에(-) 접근(access)하지 않은 파일과 디렉토리를 리스트로 만들려면(-atime)?
    - 자신의 홈디렉토리에서 만 검색하려면?
    - 서브 디렉토리로 내려가지 않고 현재 디렉토리에서만 검색하려면?
    - 특정 유저(foobar) 소유의 파일을 찾을려면?
    - 퍼미션이 777인 파일을 찾을려면 ?
    - others에게 쓰기 권한이 있는 파일을 찾을려면?
    - others에게 쓰기 권한이 있는 파일을 찾아 쓰기 권한을 없애려면?
    - 유저이름과 그룹이름이 없는 파일을 찾을려면?
    - 빈 파일을 찾을려면?
    - 파일크기가 100M 이상된 파일을 찾을려면?
    - *.bak 파일을 찾아 지울려면?
    - *.bak 파일을 찾아 특정 디렉토리로 옮길려면?
    - 디렉토리 만 찾을려면?
    - root권한으로 실행되는 파일을 찾을려면?
    - 다른 파일시스템을 검색하지 않을려면?
    - 파일이름에 공백이 들어간 파일을 찾을려면?
    - 숨겨진(hidden) 파일을 찾을려면?
    - 같은 이름을 가진 디렉토리를 찾을려면?
    - 잘못된 링크를 찾을려면?

    4. find 명령어에 대해서 좀더 알아보려면?

    ------------------------------------------------------------

    1. 가장 일반적인 find 명령어

    # find /path -name "foobar" -print

    제일 먼저(?) 배우는 형식이 아닌가 쉽군요.


    2. find 명령어 일반적인 옵션

    2-1. 사용법 개요

    find 명령어 사용법 보기 :

    # find --help
    # man find (직접 입력해 보세요. 내용이 너무 많아서..)

    사용법 : find [path...] [expression]
    기본값 : default path는 현재 디렉토리; default expression은 -print

    표현식(expression) 구성 :
    operators (decreasing precedence; -and is implicit where no others are given):
    ( EXPR ) ! EXPR -not EXPR EXPR1 -a EXPR2 EXPR1 -and EXPR2
    EXPR1 -o EXPR2 EXPR1 -or EXPR2 EXPR1 , EXPR2
    options (always true): -daystart -depth -follow --help
    -maxdepth LEVELS -mindepth LEVELS -mount -noleaf --version -xdev
    tests (N can be +N or -N or N):
    -amin N -anewer FILE -atime N -cmin N
    -cnewer FILE -ctime N -empty -false -fstype TYPE -gid N -group NAME
    -ilname PATTERN -iname PATTERN -inum N -ipath PATTERN -iregex PATTERN
    -links N -lname PATTERN -mmin N -mtime N -name PATTERN -newer FILE
    -nouser -nogroup -path PATTERN -perm [+-]MODE -regex PATTERN
    -size N[bckw] -true -type [bcdpfls] -uid N -used N -user NAME
    -xtype [bcdpfls]
    actions:
    -exec COMMAND ; -fprint FILE -fprint0 FILE -fprintf FILE FORMAT
    -ok COMMAND ; -print -print0 -printf FORMAT -prune -ls

    간단하게 몇가지만 알아보죠...
    (자세한 사용설명은 꼭 man 페이지를 읽어보세요....한글은 없군요..T.T)


    2-2. 일반적으로 표현식 옵션 구분

    -a'xxxx'
    'xxxx'에 대한 Access(접근)
    -c'xxxx'
    'xxxx'에 대한 Changes(변경), 마지막으로 Access한 경우 변경됨
    -m'xxxx'
    'xxxx'에 대한 Modify(수정), 파일내용 자체 수정한 경우
    -i'xxxx'
    'xxxx'(inum 제외)에 대한 Insensitive(대소문자 구분없이)

    3-3. 자주 사용되는 표현식 옵션

    N
    정확하게 N과 일치
    +N
    N 보다 큰 경우
    -N
    N 보다 작은 경우
    -name PATTERN
    PATTERN에 일치하는 파일 찾기, 와일드카드 문자 사용가능
    -iname PATTERN
    PATTERN에 일치하지 않은(insensitive) 파일 찾기
    -perm [+-]mode
    PERMission('mode')에 해당되는 파일 찾기, ls와 결합 가능
    -type [bcdpfls]
    b(블럭파일), c(특정 문자), d(디렉토리), p(파이프),
    f(정규표현 일반파일), l(링크), s(소켓) 유형의 파일 찾기
    -size N[bckw]
    파일 크기가 N 인 파일 찾기
    b(블럭-기본값), c(bytes), k(kbytes),
    w(2바이트 단어)
    -user NAME
    NAME은 유저이름이거나 UID
    -atime N
    N*24 시간 동안에 Access 한 파일
    -ctime N
    N*24 시간 동안에 Changes 한 파일(내용수정이 아니고 읽기모드도 Changes됨)
    -mtime N
    N*24 시간 동안에 Modify 한 파일
    -empty
    파일이 비어 있고(0 bytes), 정규식 파일이거나 디렉토리
    -newer FILE
    FILE 보다 최근에 갱신된 파일
    -path PATTERN
    path가 PATTERN과 일치하는 path에 대해서 검색
    -regex PATTERN
    파일이름이 PATTERN에 일치하는 정규식에 대해서 검색
    -inum N
    inode N을 갖는 파일
    -nouser,-nogroup
    USER나 GROUP에 이름이 없는 파일 검색(UID,GID만 있는 파일)
    -exec COMMAND
    검색된 파일을 찾으면 COMMAND 명령을 실행한다.
    COMMAND 인자(검색된 파일)는 {}으로 사용하며,
    이때 COMMAND 끝은 ;(;이 아님)을 사용해야 한다. 즉 명령구분
    문자인 ';'을 탈출()시켜줘야 한다.
    -ok COMMAND
    -exec COMMAND와 같지만 COMMAND를 실행하기 전에 확인을 요청한다.

    3-4. path(find 명령어 다음의 path)
    .
    현재 디렉토리(기본값이므로 생략해도 됨)
    `pwd`
    현재 디렉토리와 결합(?) `은 ~문자가 있는 자판
    $(pwd)
    위의 `pwd`와 같거나 비슷함
    /
    최상위 루트 디렉토리에서 하위 모든 디렉토리
    /home
    특정 /home 디렉토리에서 하위 모든 디렉토리
    /{usr,home/{aaa,san2},var}
    /usr, /usr/home/aaa /usr/home/san2 /var

    3-5. 표현식-연산자

    ( 표현식 )
    '표현식'을 우선적으로 먼저 수행
    (와 )앞에 를 넣어야 하며, '표현식'과 공백을 각각 둔다.
    ( A + B ) * ( C + D ) 와 같이 (, )안을 우선적으로 수행
    ! 표현식 , -not 표현식
    '표현식'을 부정
    표현식1 -a 표현식2, 표현식1 -and 표현식2
    표현식1과 표현식2의 AND 연산
    표현식1 -o 표현식2, 표현식1 -or 표현식2
    표현식1과 표현식2의 OR 연산


    3. 예제

    3-1. 다른 명령어와 결합 형태(ls,xargs)

    찾는 것 그 차체 만으로 만족(?) 할 수 도 있지만 그 결과에 대해서
    어떤 행동(Actions)을 취할 필요가 있습니다.

    형태1. -exec 이용시

    # find ..... -exec COMMAND {} ;

    형태2. xargs 명령어로 표준 입력받아 COMMAND 수행

    # find ..... | xargs COMMAND

    형태3. ls 명령어로 최종 결과 출력

    # ls -l `find .....[COMMAND]`
    또는
    # find .... ls
    (ls는 ls -dils와 같음)

    xargs
    xargs rpm 정보보기
    # rpm -qi `rpm -qf $(which xargs)`
    또는
    # rpm -qf `which xargs` | xargs rpm -qi

    즉, find 결과에 대해서,

    형태1은 -exec를 사용하여 그 인자를 {}로 사용하고,

    형태2는 xargs 명령어로 find에서 넘어온 결과(표준출력)에 대해서 COMMAND를 실행하고,

    형태3은 오른쪽의 find 결과물에 대해서 ls 명령어를 실행합니다.
    간혹 '/bin/ls Argument list too long'이라는 에러를 낸 경우도 있습니다.
    이는 검색조건에 너무 많은 와일드카드 문자로 찾을 경우에 그렇습니다.
    이를 테면 /*/*/*.*/.*,

    `은 ~문자가 있는 자판(역인용부호).

    ls -l 명령어를 사용할 경우, 찾는 결과가 없다면 모두 출력됩니다.
    (ls -l와 같기 때문에)
    ls 명령어와 마찬가지로 다른 명령어(chmod, chmod)를 결합하여 사용할 경우 그 찾는
    결과가 없다면 명령어에 대한 에러를 내겠죠.
    (chmod 'null')과 같은 예..........

    # find /{home,usr/{src,local/src}} -nouser -o -nogroup -exec ls -l {} ; -print | more
    # find /{home,usr/{src,local/src}} -nouser -o -nogroup -print | xargs ls -l | more

    위의 2개의 명령어 대해서 직접 테스트 해보세요...

    전자의 경우, 아마 아무것도 출력되지 않을 겁니다.

    # find /{home,usr/{src,local/src}} ( -nouser -o -nogroup ) -exec ls -l {} ; -print | more

    위와 같이 해야 맞겠죠...(우선순위)

    후자의 경우도 마찬가지로 다음과 같이 우선순위를 정해놓아야 겠지요..
    아마 원하는 출력이 이 경우일 것 같군요.

    # find /{home,usr/{src,local/src}} ( -nouser -o -nogroup ) -print | xargs ls -l | more


    3-2. 퍼미션 관련 예제

    othesrs에 쓰기(w:2) 권한이 있는 모든(-기호를 붙임) 파일 리스트를 찾을려면?

    # find `pwd` -perm -2 -print | xargs ls -l

    여기에서 2는
    퍼미션이 -------w- 와 일치하는 파일이며 -의 의미는 rwx-중 하나.

    왜 2인가요?
    만약 퍼미션이 755 이라면,

    700 : rwx------ : user
    50 : ---r-x--- : group
    5 : ------r-x : others
    ------------------------
    755 : rwxr-xr-x : others는 읽기와 실행 권한

    따라서 others의 권한은 8진수로 5(r+x)이다.

    그렇다면, others가 쓰기(w:2) 권한은 당연히 -------w-

    그룹이나 others에게 쓰기 권한이 있는 파일일 경우

    -perm -20 -o -perm -2

    그룹과 others에게 모두 쓰기 권한이 있는 파일일 경우

    -perm -22

    [others에게 w 권한이 있는 파일에 w 권한 없애기]

    방법1)
    1. others에게 w 권한이 있는 파일 리스트 출력

    # find `pwd` -perm -2 -print | xargs ls -l | more
    (만약 매치되는 리스트가 없다면 전부 출력함)

    2. others에게 w 권한을 없애기

    # find `pwd` -perm -2 -print | xargs chmod o-w
    (만약 매치되는 리스트가 없다면 chmod에 에러를 냄)

    방법2) 방법1)의 과정을 한꺼번에 할 경우

    # find `pwd` -perm -2 -exec chmod o-w {} ; -print | xargs ls -l
    또는
    # ls -l `find $(pwd) -perm -2 -print | xargs chmod o-rwx` | more

    이 경우는 퍼미션이 조정된 결과를 출력함.


    3-3. 유저와 관련된 예제

    UID와 GID에 대한 유저가 없는 파일을 root.root로 바꾸어 보죠.

    1) 먼저 리스트를 출력해 보자.(확인해야하니깐)

    # find . ( -nouser -o -nogroup ) -print | xargs ls -l | more

    2) 확인했으면, chown root.root 명령을 내리자.

    # find . ( -nouser -o -nogroup ) -print | xargs chown root.root | more
    또는
    # find . ( -nouser -o -nogroup ) -exec chown root.root {} ; -print | xargs ls -l
    (chown root.root 의 결과를 ls -l)


    3-4. 유용한 팁

    *주의) ***********************************************
    -a'xxxx'
    'xxxx'에 대한 Access(접근), 읽기
    -c'xxxx'
    'xxxx'에 대한 Changes(변경), 마지막으로 Access한 경우에도 변경됨
    -m'xxxx'
    'xxxx'에 대한 Modify(수정), 파일내용 자체 수정한 경우
    *****************************************************

    - 최근 하루(1) 동안(-)에 변경(change)된 파일을 찾을려면(-ctime)?

    # find / -ctime -1 -a -type f | xargs ls -l | more

    - 오래된 파일을 찾을려면(30일 이상 수정(modify))되지 않은)?

    # find / -mtime +30 -print | more

    - 최근 30일(30) 안에(-) 접근(access)하지 않은 파일과 디렉토리를 리스트로 만들려면(-atime)?

    # find / ! ( -atime -30 -a ( -type d -o -type f ) ) | xargs ls -l > not_access.list

    - 자신의 홈디렉토리에서 만 검색하려면?

    # find $HOM ...
    또는
    # find ~root ...

    - 서브 디렉토리로 내려가지 않고 현재 디렉토리에서만 검색하려면?

    # find . -prune ...

    - 특정 유저(foobar) 소유의 파일을 찾을려면?

    # find / -user foobar -print | more

    - 퍼미션이 777인 파일을 찾을려면 ?

    # find / -perm 777 -print | xargs ls -l | more

    - others에게 쓰기 권한이 있는 파일을 찾을려면?

    # find / -perm -2 -print | xargs ls -l | more

    - others에게 쓰기 권한이 있는 파일을 찾아 쓰기 권한을 없애려면?

    # find / -perm -2 -print | xargs chmod o-w
    또는
    # find / -perm -2 -exec chmod o-w {} ; -print | xargs ls -l | more

    - 유저이름과 그룹이름이 없는 파일을 찾을려면?

    # find / ( -nouser -o -nogroup ) -print | more

    - 빈 파일을 찾을려면?

    # find / -empty -print | more
    또는
    # find / -size 0 -print | more

    - 파일크기가 100M 이상된 파일을 찾을려면?

    # find / -size +102400k -print | xargs ls -hl

    - *.bak 파일을 찾아 지울려면?

    # find / -name "*.bak" -exec rm -rf {} ;

    - *.bak 파일을 찾아 특정 디렉토리로 옮길려면?

    # mv `find . -name "*.bak"` /home/bak/

    - 디렉토리 만 찾을려면?

    # find . -type d ...

    - root권한으로 실행되는 파일을 찾을려면?

    # find / ( -user root -a -perm +4000 ) -print | xargs ls -l | more

    - 다른 파일시스템을 검색하지 않을려면?

    # find / -xdev ...

    - 파일이름에 공백이 들어간 파일을 찾을려면?

    # find / -name "* *" -print

    - 숨겨진(hidden) 파일을 찾을려면?

    # find / -name ".*" -print | more

    - 같은 이름을 가진 디렉토리를 찾을려면?

    # find / -type d -print | awk -F/ '{printf("%st%sn",$NF,$0);}' | sort| more
    *주)'O'Reilly Unix Power Tools' 참고

    - 잘못된 링크를 찾을려면?

    # find . -type l -print | perl -nle '-e || print' | xargs ls -l
    *주)'O'Reilly Unix Power Tools' 참고
    2006/09/08 23:11 2006/09/08 23:11
    이 글에는 트랙백을 보낼 수 없습니다
    출처 블로그 > 일기와 개발백서입니다.
    원본 http://blog.naver.com/baltasar/100002719983

    2년 전에 작성해놨던 문서인데 내용이 워낙 부실해 공유를 할까말까 하다가 제 블로그에 공유하게 되는군요.


    ----------------------------------------------------------------------------------------


    리눅스상에 Postgres 설치해서 JDBC 셋팅하기

    * 준비사항
    jdk1.3.X(postgres 7.2.2에서는 jdk1.4를 사용할 경우 컴파일 에러가 납니다.)
    jakarta ant
    j2sdkee
    postres 7.2.2 소스버전


    1. http://www.postgresql.org에서 postgres를 소스 버전으로 다운 받는다.
      요즘 유행하는 패키지(RPM)를 구하긴 했었는데 의존성 문제로 포기했음.
      예전에 의존성 문제로 죽는줄 알아서 -_-

    2. 루트계정으로 접속해 소스 압축을 풀어준다.
      /usr/local/tar xzvf postgresql-7.2.1.tar.gz

    3. 설치 하기 전에 환경 설정해주기
      위치는 /usr/local/pgsql로 odbc와 jdbc 드라이버를 함께 설치해야 함.
      그리고 jdbc드라이버의 컴파일을 ant로 하기 때문에 ant가 깔려있어야 합니다.
      ./configure --prefix=/usr/local/pgsql --enable-locale --enable-multibyte --enable-nls --enable-odbc --with-java
      (enable-multibyte 안하시면 UTF-8 개발 쫑~ 입니다.)

    4. 컴파일
      gmake

    5. 컴파일 검사. (본인은 DB 초기화시에 에러가 났으나 문제는 없음)
      gmake check

    6. 설치
      gmake install

    여기서 끝난게 아닙니다.
    관리 계정을 추가하고 공유라이브러리를 셋팅하고 DB스페이스(거대한 통짜DB)와 사용자별DB를 생성해야 합니다.
    7. 관리 계정 추가하기
      adduser postgres

    8. 공유라이브러리 셋팅하기
      bash의 경우 .bash_profile에 다음과 같이 설정합니다.
      LD_LIBRARY_PATH=/usr/local/pgsql/lib
      export LD_LIBRARY_PATH
      쉘 상에서 여러명이 DB를 사용할테니 /etc/profile에 설정하는게 좋겠죠?

    9. DB스페이스 생성하기
      DB스페이스가 설치될 디렉토리를 만들고
      mkdir /usr/local/pgsql/data
     
      DB스페이스 디렉토리의 소유자를 관리 계정으로 바꾸고
      chown postgres /usr/local/pgsql/data

      계정을 관리 계정으로 바꿔서
      su -l postgres

      DB스페이스를 생성합니다.
      /usr/local/pgsql/bin/initdb -E EUC_KR -D /usr/local/pgsql/data
    -E옵션은 한글 정렬을 위해 반드시 넣어야 합니다.


    제대로 설치했다면 다음과 같은 메세지가 뜰 겁니다.
    [zodiac:postgres]~ # /usr/local/pgsql/bin/initdb -E EUC_KR -D /usr/local/pgsql/data
    The files belonging to this database system will be owned by user "postgres".
    This user must also own the server process.

    Fixing permissions on existing directory /usr/local/pgsql/data... ok
    creating directory /usr/local/pgsql/data/base... ok
    creating directory /usr/local/pgsql/data/global... ok
    creating directory /usr/local/pgsql/data/pg_xlog... ok
    creating directory /usr/local/pgsql/data/pg_clog... ok
    creating template1 database in /usr/local/pgsql/data/base/1... ok
    creating configuration files... ok
    initializing pg_shadow... ok
    enabling unlimited row size for system tables... ok
    creating system views... ok
    loading pg_description... ok
    vacuuming database template1... ok
    copying template1 to template0... ok

    Success. You can now start the database server using:

       /usr/local/pgsql/bin/postmaster -D /usr/local/pgsql/data
    or
       /usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l logfile start

    만약 사용자를 바꾸는걸 깜빡 했다면
    [zodiac:postgres]/usr/local # /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data
    The files belonging to this database system will be owned by user "postgres".
    This user must also own the server process.

    creating directory /usr/local/pgsql/data... mkdir: cannot create directory `/usr/local/pgsql/data': 허가 거부됨

    initdb failed.
    아마도 이런 메세지가 뜨겠지요.

    자 그럼 DB를 시작시켜 봅시다.
    DB를

    * 시작하기
    /usr/local/pgsql/bin/postmaster -i -D /usr/local/pgsql/data
    -i옵션은 TCP/IP접속을 허용합니다. 외부에서 접속한다면 당연히 해야겠죠?

    매번 하기 귀찮으면 관리 계정의 .bash_profile에 다음과 같이 설정합니다.
    export PGDATA=/usr/local/pgsql/data
    그러면 다음부터는
    /usr/local/pgsql/bin/postmaster -i
    이것만 하셔도 DB가 시작됩니다.

    * 중지하기
    pgsql/bin/pg_ctl stop
    이전 버전에 따라서는 그냥 kill 시켜야 되는 것도 있습니다.

    10. 인제 진짜 마지막입니다.
    물리DB를 계정별로 쪼개 쓸 논리공간을 할당을 해야 합니다.
    관리 계정으로 /usr/local/pgsql/bin으로 이동해서 사용자 DB를 만듭시다.
    /usr/local/pgsql/bin/createdb postgres
    만약 DB를 시작하지 않고 사용자 DB를 만들었다면 다음과 같은 메세지가 뜹니다.
    [zodiac:postgres]/usr/local/pgsql/bin # createdb postgres
    psql: could not connect to server: Connection refused
           Is the server running locally and accepting
           connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
    createdb: database creation failed

    그리고 이전에 postgres를 설치하셨던 분들이 자주 부딪치는 에러는..
    [zodiac:postgres]/usr/local/pgsql/bin # ./postmaster
    FATAL 1:  Can't read lock file /tmp/.s.PGSQL.5432.lock: Permission denied

    루트로 접속 후 /tmp에 가서 .s.PGSQL로 시작되는 파일을 전부 제거해 주시면 해결됩니다.

    그다음에 JDBC 드라이버 사용을 위해 /etc/profile에 classpath를 추가합니다.
    추가항목: /usr/local/pgsql/share/java/postgresql.jar

    11. 연습으로 쓰실거라면 이게 전부지만..
    서비스를 한다면 접속부분을 정의해야 되겠죠?
    그러기에 앞서 pgsql을 실행하고 관리계정의 암호를 지정해 줍니다.

    alter user postgres with password '패스워드';

    그리고 psql터미널을 종료한 후
    pgsql/data/pg_hba.conf의 접속옵션 부분을 다음과 같이 변경합니다.
    (postgres는 초기설정상 패스워드 입력으로는 터미널 접속을 불허하도록 되어 있습니다.)

    local        all          all                                            password
    host         all          all          0.0.0.0       0.0.0.0             password

    그다음에 pgsql/bin/pg_ctl reload를 수행해 갱신합니다.
    그러면 그다음 부터는 접속시 패스워드를 넣어야 접속이 가능해집니다.

    이상으로 설치를 마칩니다.




    위의 설정에서 내부 로케일 변환 문제가 발생되었습니다.

    설치시 다음과 같이 변경하세요.

    // 현재 시스템의 한글 설정상태 확인

    [server1:main]~ # echo $LANG
    ko_KR


    //db 초기화에 다국어 셋팅하기

    [server1:main]~ # initdb -no-locale --lc-collate=C -E utf-8


    [server1:main]~ # createdb -E utf-8 testdb


    이렇게 하면 클라이언트 터미널에서 문제가 생길겁니다.

    다음과 같이 셋팅하여 UTF-8을 클라이언트에서 지원하도록 합시다.

    set client_encoding = 'uhc';

    2006/09/08 22:43 2006/09/08 22:43
    이 글에는 트랙백을 보낼 수 없습니다
    Linux  2006/09/08 22:41
    출처 카페 > 운영체제 공부 / 쩡희
    원본 http://cafe.naver.com/jeonghee1004/17
    stow는 프로그램을 직접 컴파일하여 설치할때, 삭제 제거를 쉽게 할 수 있도록 도와주는 프로그램입니다.

    일반적으로 직접 컴파일한 소스는 /usr/local 아래에 설치되며, 이렇게 설치된 프로그램이 늘면 제거하거나 업데이트 하기에 어렵습니다. 그래서 /usr/local/<프로그램명>-<버전> 아래에 설치하기도 하는데, 이것은 삭제와 제거가 쉽지만 프로그램 binary, header, library, man page를 사용하는데에는 불편함이 따릅니다. 이때 stow를 사용하여 프로그램을 /usr/local 아래로 link, unlink 하면 경로로 인한 불편함도 없어지고 프로그램 설치와 제거가 쉬워집니다.

    stow가 사용할 디렉토리를 만듭니다.
    인용:
    mkdir /usr/local/stow

    다음과 같이 컴파일하여 설치합니다.
    인용:
    ./configure --prefix=/usr/local/stow/<프로그램이름>
    make
    make install

    /usr/local/stow 아래에 설치된 프로그램을 /usr/local로 링크합니다.
    인용:
    cd /usr/local/stow
    stow <프로그램이름>  

    제거할때는 다음과 같이 명령하면, 프로그램이 열심히 링크를 찾아 지워줍니다.
    인용:
    cd /usr/local/stow
    stow -D <프로그램이름>

    2006/09/08 22:41 2006/09/08 22:41
    이 글에는 트랙백을 보낼 수 없습니다
    Linux  2006/09/08 22:39
    출처 블로그 > Linux & Server & Music ~★
    원본 http://blog.naver.com/paradox1573/40013015745

    유닉스 혹은 리눅스용 커맨드 팁 모음입니다.


    1. 서브 디렉토리까지 파일안의 문자열 모두 검색
    2. haha와 huhu가 동시에 들어있는 행 뽑기
    3. 찾아서 지우기
    4. 공사중에 로그인 막기
    5. 크기가 가장 큰 파일, 디렉토리 찾기
    6. 가장 큰 파일을 찾으려면
    7. 현재 디렉토리의 크기만을 파악할때
    8. 시스템 정보 감추기
    9. 어떤 프로세스가 메모리를 가장 많이 잡아먹고 있는지 알아내기
    10. FTP로 들어온 사용자 확인하기
    11. 원하지 않는 사용자 죽이기
    12. less 결과를 vi로 보기
    13. vi에서 블럭 설정하기
    14. man 페이지 프린트하기
    15. ping 무시하기
    16. LILO 다시 살리기
    17. 특정 사용자 ftp 접근 막기
    18. X 윈도우에서 TV보기
    19. ls라는 파일이 포함된 rpm패키지 찾기
    20. 현재 rpm패키지의 의존패키지
    21. 현재 디렉토리크기
    22. 바로 이전 디렉토리로 가기
    23. 프로세스명으로 프로세스 죽이기
    24. 하드웨어 시계맞추기
    25. 원격에서 리모트서버의 X application실행시
    26. 링크 파일
    27. ^M 문자 없애기
    28. 비어있는 행을 찾기
    29. 기타 명령어 떼
    30. 각자가 사용하는 컴퓨터의 정보를 알고 싶을때
    31. 전체 메일
    32. 디렉토리만 빠르게 검색
    33. 호스트 네임 바꾸기
    34. 틀린명령어 틀린글자만 바꿔서 실행
    35. 유닉스의 현재 버젼과 종류 그리고 라이센스등을 알려주는 명령어
    36. 열려있는 포트 알아내기
    37. 텔넷 모든 접속자에게 메세지 보내기
    38. lsof는 열려있는 파일을 나타내 주는 옵션
    39. 사용자가 어디에서 무엇을 하는지 알아내기
    40. 텔넷 화면 수정
    41. 하위 디렉토리 한꺼번에 만들기
    42. 특정디렉토리의 모든 파일 안의 특정 문자열 치환
    43. killall 명령 시뮬레이션 (프로세스명으로 죽이기)
    44. find와 grep
    45. vi 검색, 치환
    46. 파일내의 중복되는 행을 제거 : uniq
    47. 파일의 결합
    48. 파일의 암호화 : crypt
    49. 개행을 제외한 화면내의 보이지 않는 문자 출력
    50. 화일내의 포함된 특정문자열로 찾아서 내용만 출력하기
    51. 특정 파일의 화일명을 비슷하게 여러개 한꺼번에 바꾸기
    52. 어제 날짜 구하기
    53. 원하지 않는 사용자 죽이기
    54. UNIX상에서 한글출력이 깨져 나올경우
    55. 현재 디렉토리의 대량의 파일을 각자의 파일명가운데에 특정문자 추가하여 바꾸기

    0.0.0.1 서브 디렉토리까지 파일안의 문자열 모두 검색

    find ./ -name "*" -exec grep 'abc' {} \; -print find . -name -print -exec grep abc {} \; grep -r abc * 

    0.0.0.2 haha와 huhu가 동시에 들어있는 행 뽑기

    grep haha foo.txt | grep huhu 

    0.0.0.3 찾아서 지우기

    find / -name "*.eml" -exec rm -f {} \; 

    0.0.0.4 공사중에 로그인 막기

    시스템을 공사중일 때, root 이외의 다른 사용자를 로그인 못하게 해야 할 때가 있죠? 그럴 때는, /etc/nologin 이라는 파일을 만들어,공사중 또는 Under Construction이라는 공지를 넣으면 됩니다.

    0.0.0.5 크기가 가장 큰 파일, 디렉토리 찾기

    가장 큰 디렉토리를 찾으려면, du -S | sort -n

    0.0.0.6 가장 큰 파일을 찾으려면

    ls -lR | sort +4n

    0.0.0.7 현재 디렉토리의 크기만을 파악할때

    [root@dev2 local]# du -c -h --max-depth=0 * 6.4M    apache 35M     bin 43M     dns 1.7M    doc 42k     etc 1.0k    games 42k     geektalkd 1.1M    gnuws 1.1M    include 41k     info 19M     jakarta-tomcat-3.2.3 0       jre 15M     jre118_v3 25M     lib 62k     libexec 1011k   man 1.3M    mm.mysql.jdbc-1.2c 937k    sbin 3.8M    share 1.8M    shoutcast-1-8-3-linux-glibc6 5.2M    ssl 159M    total 

    0.0.0.8 시스템 정보 감추기

    /etc/inetd.conf 파일을 열어서,
    telnet stream tcp nowait root /usr/sbin/tcpd in.telnetd -h 

    0.0.0.9 어떤 프로세스가 메모리를 가장 많이 잡아먹고 있는지 알아내기

    ps -aux | sort +4n 또는 ps -aux | sort +5n

    0.0.0.10 FTP로 들어온 사용자 확인하기

    ftpwho,ftpcount

    0.0.0.11 원하지 않는 사용자 죽이기

    [root@dream /root]# skill -KILL sunny

    위의 명령을 내리면 sunny 라는 사용자를 완전히 추방시킬수 있습니다. 그런데 이렇게 완전히 추방시키는게 아니구, 특정 터미널에 접속해있는 사용자만 추방시켜야 할 때도 있겠죠? 그럴때는

    [root@dream /root]# skill -KILL -v pts/14

    이런식으로 하면 된다 그럼 pts/14 에 연결되어 있는 사용자가 죽게 됩니다.

    0.0.0.12 less 결과를 vi로 보기

    less상태에서 v를 누르면 바로 vi로 감

    0.0.0.13 vi에서 블럭 설정하기

    alt+v 하면, 라인 단위로 블럭 설정을 할 수 있으며, 해제 하시려면 Esc를 누르면 됩니다. 또한 ctl+v를 하시면, 블럭 단위로 블럭을 설정하실 수 있습니다.

    블럭을 설정 하신 뒤,

    삭제를 하려면 x 복사를 하려면 y 붙여넣기는 p

    0.0.0.14 man 페이지 프린트하기

    man -t vi > vi.ps

    0.0.0.15 ping 무시하기

    echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all 

    0.0.0.16 LILO 다시 살리기

    boot : vmlinuz root=/dev/hda6

    0.0.0.17 특정 사용자 ftp 접근 막기

    /etc/ftpusers 파일에 로그인 네임을 추가하면 됩니다.

    0.0.0.18 X 윈도우에서 TV보기

    리눅스에서 TV보기 위해서는 드라이버 파일과 TV를 보는 프로그램이 필요합니다. 이 글에서는 미지 리눅스 OS에 탑재된 bttv 칩셋을 사용하는 TV 카드를 기준으로 설명합 니다. 만일 커널을 새로 컴파일 하실 분은 반드시 Character devices -> Video For Linux -> BT848 Video For Linux 항목을 모듈화 시키거나 커널에 포함하십시오.

    TV 카드를 리눅스에 인식시키기 위해서 /etc/conf.modules 파일에 다음과 같은 내용을 삽입하고 컴퓨터를 다시 시작합니다.

    alias char-major-81 bttv  # 필립스 튜너의 경우 pre-install bttv modprobe -k tuner # 알프스 튜너의 경우 pre-install bttv modprobe -k tuner type=9 

    이제 kwintv나 xawtv 등의 TV 시청 프로그램으로 TV를 볼 수 있습니다. 만약 TV 장치를 찾지 못하는 오류가 있다면 bttv driver 디렉토리에 포함된 MAKEDEV 를 실행하십시오.

    0.0.0.19 ls라는 파일이 포함된 rpm패키지 찾기

    일단 ls의 절대경로를 알아야 한다. which lswhich로 알아낸 ls의 절대경로로 rpm질의를 한다.
    rpm -qf /bin/ls [root@piruks /etc]# which ls /bin/ls [root@piruks /etc]# rpm -qf /bin/ls fileutils-4.0i-2mz 

    0.0.0.20 현재 rpm패키지의 의존패키지

    rpm -qR 패키지명

    0.0.0.21 현재 디렉토리크기

    du -h --max-depth=1 . 

    0.0.0.22 바로 이전 디렉토리로 가기

    cd - 

    0.0.0.23 프로세스명으로 프로세스 죽이기

    killall 프로세스명 kill -9 `pidof 프로세스명 

    0.0.0.24 하드웨어 시계맞추기

    배포본을 설치하고 나면 시간이 맞지 않는 경우가 많다. 간단히 어느정도 정확한 시간을 설정하는 방법이다.
    [root@dev /down]# rdate -s time.kriss.re.kr [root@dev /down]# clock -w 

    0.0.0.25 원격에서 리모트서버의 X application실행시

    X윈도 app를 실행할때 다음과 같은 에러가 나면 조치
    [kang@dev /home/kang] xclock Xlib: connection to "211.222.186.170:0.0" refused by server Xlib: Client is not authorized to connect to Server Error: Can't open display: 211.222.186.170:0.0  export DISPLAY=211.222.186.170:0 xhost +211.222.186.170 

    0.0.0.26 링크 파일

    ln -sf 링크할디렉토리 링크로 만들어질 디렉토리 참고로 링크를 걸기만 한다고 접근가능한것은 아니고,링크가 걸린 디렉토리의 퍼미션도 허용으로 바꿔야 한다. 링크로 만들어질 디렉토리는 저절로 생성되고 퍼미션 777로 잡혔음. ln -sf /www/dir_1/r_photo /www/dir_2/r_photo

    0.0.0.27 ^M 문자 없애기

    a = 1^M def vartest(a):^M a = a + 1^M return a^M a = vartest(a)^M print a^M  
    Unix류 기계에서는 그냥 ^J 하나만을 개행문자로 사용하는데 PC에서는 MJ 이렇게 두 제어문자가 연속으로 사용되어야 개행문자로 받아들이죠. (그래서 PC쪽에서 만들어진 txt문서를 유닉스 기계로 불러와 vi 등을 실행하면

      줄 끝마다 보기싫은 ^M이 붙습니다. 뭐 vi에서 요거 지우는건 간단하지만요.)

    PC에서 Unix에서 작성한 텍스트 문서를 보통 ftp로 받아오거나 하면 워드패드 등에서 봤을 때 전혀 개행이 되어있지 않지요. 하지만 MS Word 등 좀더 강력한 편집기에선 대개 잘 처리해서 잘 보여줍니다.

    위는 간단한 Python 소스입니다. 위의 경우 처럼 ^M문자가 있을때, dos2unix라는 유틸리티를 많이 사용하기도 하죠. 하지만 vi에서 간단하게 모두 삭제할수도 있습니다. dos2unix가 없거나 빠져나가서 지우는게 귀찮을때 좋겠죠. 명령은 :%s/(ctrl+v)M//g 입니다. (ctrl+v)M 이거는 ctrl과 v를 눌러준후, ctrl키를 떼지 말고 바로 m을 눌러주시믄 됩니다. 위는 정규표현식을 이용한것이고, 형식은 %s/이것을/요걸로/g 입니다 그럼 문서안의 모든 "이것을" "요걸로" 바꾸게 되죠. 단, M의 경우 ctrl+M의 뜻인데 단순히 문자로 M을 바꾸라도 해도 인식을 못하기 때문에, 위처럼 (ctrl+v)M 으로 해주셔야 합니다.

    0.0.0.28 비어있는 행을 찾기

    #grep -n '^$' filename 정규표현 의미 ^ 행의 처음 $ 행의 끝 . 임의의 한 문자
    [...] ... 안의 임의의 한 문자. a-z,0-9 같은 범위도 사용 [^..] .. 안에 없는 임의의 한 문자. 범위 사용가능 r* 0회 이상 r 반복 r+ 1회 이상 r 반복 r? 0 혹은 1회의 r r{n,m} n회 이상 m회 이하 r 반복 r1|r2 r1 혹은 r2 (egrep 만) (r) r 의 정규표현(egrep 만) 

    0.0.0.29 기타 명령어 떼

    alias(명령어 간소화하기) apropos(관련된 명령어 찾기) arch(컴퓨터 종류 알기) arp(같은 서브넷의 IP 보여주기) at(작업 시간 정하기) atd(계획성 있는 작업 실행하기) awk(특정 패턴 문자 처리하기) a2p(펄 파일로 바꾸기) badblocks(배드 블럭 검사하기) bc(계산기) biff(메일 수신 소리로 확인하기) bg(후면작업; 배경화면 설정) bind(키나 함수 순서 결합하기) break(루프 빠져나가기) cal(달력보기) builtin(내부 명령어 알아보기) case(조건 처리하기) cat(화면상에서 파일 보기) cd(디렉토리 변경하기) cfdisk(디스크 설정하기) chattr(파일 속성 변경하기) chfn(사용자 정보 변경하기) chgrp(파일, 디렉토리가 속했던 그룹 바꾸기) chmod(파일 권한 바꾸기) chown(파일 주인 바꾸기) chsh(지정된 셸 바꾸기) cksum(CRC값을 점검한다) clear(화면 청소하기) clock(CMOS 시각을 조정하기) cmp(파일 비교하기) colcrt(문자 변환 필터) colrm(열 삭제하기) column(가로 정렬하기) comm(파일 비교 출력하기) command(명령어 알아보기) continue(루프 계속돌기) cp(파일 복사하기) cpio(복사본 만들기) crontab(cron을 관리한다) csplit(파일에 서식, 규칙 정하기) cut(필요한 필드만 출력하기) date(날짜 보기) dd(블럭장치 읽고 쓰기) debugfs(ext2 파일 시스템 디버깅하기) declare(변수 선언하기) df(파일 시스템의 사용량 보기) dirs(디렉토리 목록 표시하기) dmesg(부팅 메시지 보기) dnsdomainname(DNS 이름 출력) domainname(NIS 이름 출력&설정) du(디렉토리와 파일의 용량 파악하기) dumpe2fs(파일 시스템 정보 보기) echo(표준 출력하기) eject(장치 해제하기) elm(메일 관련) enable(내부 명령어 지정) env(환경변수 출력하기) eval(인수 읽기) exec(셸 명령어 실행하기) exit(종료하기) expand(탭을 공백으로 변환하기) export(변수 지정하기) e2fsck(파일 시스템 복구하기) fc(지정된 편집기 받기) fdformat(플로피 디스크 포맷하기) fdisk(파티션 나누기) fg(지정된 작업을 전면 프로세스로 시작하기) file(파일 종류 보기) find(파일 찾기) finger(사용자 정보 알기) fold(정형화하기) fmt(정형화하기) for(반복 실행하기) free(메모리 사용량 알아보기) fsck(파일 시스템 검사하기) fstab(파일 시스템에 대한 고정적인 정보 저장하기) ftp(파일 전송 프로그램) fuser(프로세스 ID 출력) getkeycodes(매핑 테이블 출력하기) grep(특정 문자(열) 검색하기) gzexe(실행 파일 압축하기) gzip(압축하기) halt(시스템 종료하기) hash(기억해 두기; index 역할) head(파일의 앞부분 출력하기) help(도움말 보여주기) host(호스트 정보 보기) history(사용 명령어 목록보기) hostname(서버 이름 알기) id(계정 정보 알기) if(조건문 실행하기) ifconfig(랜카드에 주소 할당하기) imolamod(모듈 설치하기) inetd(인터넷 서비스의 최상위 데몬) init(실행 단계 정하기) ispell(철자법 검사하기) jobs(수행중인 프로세스 알기) kbd_mode(키보드 모드 출력하기) kill(프로세스 죽이기) klogd(커널 로그 데몬) ldd(공유 라이브러리의 의존성 알기) less(페이지 단위로 출력하기) let(정규식 표현하기) lilo(부팅하기) ln(링크하기) locate(패턴에 맞는 파일 찾기) login(로그인하기) logger(시스템 로그 기록하기) logname(사용자 로그인명 보여주기) logout(로그인 셸 종료하기) look(특정 단어 검색하기) losetup(중복 장치 확인하기) lpd(프린트 데몬) lpq(현재 프린트 작업 상태 출력하기) lpr(출력하기) lprm(대기열에 있는 문서 삭제하기) ls(디렉토리 내용보기) lsattr(파일 시스템의 속성 보여주기) lsdev(하드웨어 장치 출력하기) lsmod(모듈 정보 출력하기) mail(메일 관련) make(컴파일하기) man(매뉴얼 보기) mattrib mbadblocks mcd mcopy mdel mdeltree mdir mesg(메시지를 받을 수 있는지 확인하기) mformat minfo mkdir (디렉토리 만들기) mke2fs(파일 시스템 생성하기) mkfs(파일 시스템 만들기) mknod(특수 파일 만들기) mkswap(스왑 영역 지정하기) mlabel mmd mmount mmove mpartition mount(장치 연결하기) more(화면 단위로 출력하기) mrd mren mtoolstest mtype mutt(메일 관련) mv(파일 옮기기) mzip netstat(현재 네트웍 상황 보기) nice(프로세스 우선 순위 변경하기) od(8진수로 파일 보기) passwd(암호 입력하기) pidof(실행중인 프로그램의 프로세스 ID 찾기) pine(메일 관련) ping(네트웍 확인하기) popd(pushd 취소) ps(프로세스 상태 알기) pstree(프로세스 상관관계 알기) pwd(절대경로 보여주기) quota(디스크 한계량 알기) rarp(rarp 테이블 관리하기) rcp(원격 호스트에 파일 복사하기) rdev(루트, 스왑장치, 램 크기, 비디오 모드를 조사하고 설정하기) rdate(네트웍으로 시간 설정하기) reboot(재부팅하기) rmmod(모듈 지우기) readonly(읽기 전용으로 표시하기) renice(프로세스 우선 순위 바꾸기) reset(터미널 초기화하기) restore(다시 저장하기) rlogin(바로 접속하기) rm(파일 지우기) rmdir (디렉토리 지우기) route(라우팅 테이블 추가/삭제하기) rpm(프로그램 추가/삭제) rpm2cpio(rpm을 cpio로 변환하기) rsh(원격으로 명령어 실행하기) rup(호스트 상태 출력하기) rusers(호스트에 로그인한 사용자 출력하기) rwall(호스트 사용자에게 메시지 뿌리기) script(기록하기) set(변수값 설정하기) setup(시스템 관련 설정하기) showmount(호스트의 마운트 정보 보여주기) shutdown(전원 끄기) sleep(잠시 쉬기) source(스크립트 번역하기) split(파일 나누기) ssh(암호화된 원격 로그인하기) stty(터미널라인 설정 보여주기) su(계정 바꾸기) suspend(셸 중단하기) swapoff (스왑 해제하기) swapon(스왑 활성화하기) sync(버퍼 재설정하기) syslogd(로그인 과정 설정하기) tac(거꾸로 보기) tail(문서 끝부분 출력하기) talk(이야기하기) tar(파일 묶기) tcpdchk(tcp wrapper 설정하기) tcpmatch(네트웍 요청에 대해 예측하기) tee(표준 입력으로부터 표준 출력 만들기) telnet(원격접속하기) test(테스트하기) times(셸에서의 사용자와 시스템 시간 출력하기) top(cpu 프로세스 상황 보여주기) tr(문자열 바꿔주기) true(종료 코드 리턴하기) type(유형 보기) ul(밑줄 처리해서 보여주기) ulimit(제한하기) umask(매스크 모드 설정하기) umount(장치 해제하기) unalias(별명 제거하기) uname(시스템 정보 보기) unexpand(공백 문자를 탭으로 변환하기) uniq(중복된 문장 찾기) useradd(사용자 계정 만들기) userdel(계정 삭제하기) usermod(사용자 계정정보 수정하기) unset(설정 변수 해제) uptime(시스템 부하 평균 보여주기) users(로그인된 사용자 보여주기) w(시스템에 접속한 사용자 상황 알아보기) wait(프로세스 기다리기) wall(모든 사용자에게 메시지 보내기) wc(문자, 단어, 라인수 세기) whatis(명령어의 간단한 설명보기) while(루프 명령어) who(사용자 알기) write(콘솔 상에서 간단한 메시지 보내기) xcopy(반복적으로 복사하기) XFree86 ypchfn(NIS에서 사용하는 chfn 명령어) ypchsh(NIS에서 사용하는 chsh 명령어) yppasswd(NIS에서 사용하는 passwd 명령어) zcat(압축 파일 보기) zcmp(압축 파일 비교하기) zforce(강제로 gz 만들기) zgrep(압축 상태에서 grep 실행하기) zmore(압축 상태에서 more 실행하기) znew(.Z 파일을 .gz로 다시 압축하기) 

    0.0.0.30 각자가 사용하는 컴퓨터의 정보를 알고 싶을때

    [root ...]#more /proc/cpuinfo 위와 같이 치면 사용자의 컴퓨터 정보를 볼수 있으며, [root ...]#more /proc/meminfo 라고 치면 사용자의 메모리 정보를 볼수 있습니다.

    0.0.0.31 전체 메일

    먼저 보낼 내용을 텍스트로 파일로 만들어야 합니다.어디에서든지 가능하지요! [ root@aromi /root]# vi nea 안녕하세요! 저희 서버에서는 웹서버를 오늘부터 시작합니다. 사용자 여러분의 많은 관심과 이용을 부탁드립니다.
     :wq [ root@aromi /root]# 
    만약, 한글을 사용하지 못하면 윈도우95에서 먼저 쓴다음에 ftp를 이용해서 올리면 됩니다.
    [ root@aromi /root]# mail -s "[공지]" `cat /etc/passwd|gawk ?F :'{print$1}'` 
    [공지]-> 라고 쓴 것은 보낼 메일의 제목입니다. 'cat /etc/passwd|gawk -F : '{print$1}'' ->먼저 cat으로 passwd파일의 첫번째 나오는 내용을 출력하라는 소리입니다. nea라는 텍스트파일을 메일의 내용으로 보내라는 내용입니다.

    0.0.0.32 디렉토리만 빠르게 검색

    ls -al | grep "^d"

    0.0.0.33 호스트 네임 바꾸기

    /etc/HOSTNAME file은 부팅시 /etc/sysconfig/network file 의 HOSTNAME 부분을 참조하여 저장합니다. 호스트 네임을 바꾸고자 한다면 /etc/sysconfig/network file 의 HOSTNAME 부분을 바꿔주면 됩니다.
    [ root@linux /root]# vi /etc/sysconfig/network NETWORKING=yes HOSTNAME="linux" GATEWAY="" GATEWAYDEV="" FORWARD_IPV4="yes" 
    바꾸신후 시스템을 재부팅 하신거나, #/etc/rc.d/init.d/network restart 명령을 내리시면 됩니다.

    0.0.0.34 틀린명령어 틀린글자만 바꿔서 실행

    # ./configure --prefax=/usr/local/apache 앗, 틀렸습니다. prefax가 아니라 prefix인데... 고쳐야지요...간단하게 화살표키로 왔다갔다 하면서 지워지고 바꿔주면 되겠지만 다른 방법이 있습니다. # ^fax^fix^ 라고 하면... -> ./configure --prefix=/usr/local/apache 라고 됩니다..

    0.0.0.35 유닉스의 현재 버젼과 종류 그리고 라이센스등을 알려주는 명령어

    [ root@aromi /root]# uname -a

    0.0.0.36 열려있는 포트 알아내기

    netstat -anp | grep LISTEN

    0.0.0.37 텔넷 모든 접속자에게 메세지 보내기

    wall 내용... Ctrl-D

    0.0.0.38 lsof는 열려있는 파일을 나타내 주는 옵션

    여기에 보안 점검을 위하여, -i 옵션을 사용하면, 현재 열려 있는 포트와 링크되어 있는 서비스 또는 프로그램이 모두 나타나죠. 자신이 열어 놓지 않은 포트가 열려있다던지하면 한번쯤 의심해 봐도 되겠죠?

    0.0.0.39 사용자가 어디에서 무엇을 하는지 알아내기

    w라는 명령어를 사용하시면 된답니다. 이 때, w [-s] 를 붙여주시면 -s 옵션이 긴 정보 대신에 필요한 짧은 정보만 알려 준답니다.

    0.0.0.40 텔넷 화면 수정

    로그인화면: /etc/issue.net 로그인후화면: /etc/motd

    0.0.0.41 하위 디렉토리 한꺼번에 만들기

    mkdir -p music/koreanmusic/ost

    0.0.0.42 특정디렉토리의 모든 파일 안의 특정 문자열 치환

    for i in $*; do     sed "s/paper/PAPER/g" < $i > $i.new     mv -f $i.new $i done  <chihwan.sh>  find ./(chihwan.sh를 포함하지 않는 디렉토리면) -type f -exec chihwan.sh {} \; 

    0.0.0.43 killall 명령 시뮬레이션 (프로세스명으로 죽이기)

    ps aux | grep 프로세스명 | grep -v grep | awk '{ print $w }' | xargs kill -9
    • 모든 프로세스 나열
    • 지정한 프로세스만 뽑아냄
    • grep 명령이 포함된 라인 제거
    • awk로 두번째 필드만 뽑아냄
    • xargs에 의해 걸러진 아이디로 죽임

    0.0.0.44 find와 grep

    find . -name "H20021115.*" -exec grep -l '...;........;110100' {} \;

    0.0.0.45 vi 검색, 치환

    구호스트 서비스 오늘 날짜에서 분류코드가 110100인 파일 찾기 :%s/./\U&/g

    모든문자->대문자 g/^$/d

    0.0.0.46 파일내의 중복되는 행을 제거 : uniq

    입력 파일에서 연속되는 행을 비교하여, 두 번째 이상의 동일한 행들을 제거하고 나머지는 출력파일로 출력 연속되어 표시되지 않으면 동일한 행이 존재할 수 있음.

    sort 명령을 사용하여 정렬한 후 사용하는 것이 타당 사용법uniq [-cdu] [+|숫자] [입력파일 [출력파일]] -c : 각 행이 연속적으로 나타난 횟수를 행의 시작부분에 표시 -d : 연속적으로 반복되는 행만 출력 -u : 연속적으로 반복되지 않는 행만 출력 +숫자 : 행의 처음 '숫자' 만큼의 문자는 무시 -숫자 : 행의 처음 '숫자' 만큼의 필드는 무시

    0.0.0.47 파일의 결합

    여러 개의 텍스트 파일을 하나의 파일로 순차적으로 묶는데 사용
    cat [파일명1] [파일명2] ... > [출력파일명]  cat [파일명1] [파일명2] ... >& [출력파일명]  cat [파일명1] [파일명2] ... >> [출력파일명] cat [파일명1] [파일명2] ... >>& [출력파일명] cat - [파일명1], [파일명2] .. >> [출력파일명] cat - [파일명1], [파일명2] .. >>& [출력파일명]   % cat > file1 파일명 : file1 ^D % cat > file2 파일명 : file2 ^D % cat file1 file2 > file3 % cat file3 파일명 : file1 파일명 : file2 %  

    행단위 결합 : paste 여러 파일에 대해여 행간 결합을 수행하거나 하나의 파일에 대해 연속되는 행들을 결합 둘이상의 파일에 대해서 테이블상의 하나의 열과 같이 취급하여 동일한 행번호 끼리 결합

     paste [파일명1] [파일명2].. paste -d리스트 [파일명1] [파일명2] ... paste -s [-d리스트] [파일명]  d : 행간 결합시 행간 구분문자들의 리스트 s : 한파일의 연속되는 행을 결합  % cat > paste.data1 홍길동 이순신 김유신 % cat > paste.data2 부산 서울 대구 % paste paste.data1 paste.data2 홍길동 부산 이순신 서울 김유신 대구 % paste -d"\n" paste.data1 paste.data2 홍길동 부산 이순신 서울 김유신 대구 % paste -s -d"::\n" paste.data1 홍길동:이순신:김유신 % 

    두 파일을 동일한 필드 값에 따라 행 단위 결합 : join

    관계형 데이터 베이스에서의 join 연산과 동일 키로 사용할 필드에 대해 정렬된 두 파일의 각 행에 대해 동일한 키 값을 갖는 행들을 결합 입력으로 사용될 두 파일은 키 값에 대해 오름 차순으로 정렬되어 있어야 함 출력 결과는 기본적으로 키 값이 먼저 표시되고, 첫번째 파일에서 키를 제외한 나머지 필드, 두번테 파일에서 키를 제외한 나머지 필드가 표시 필드 구분은 공백, 탭, 개행문자가 기본, 연속적으로 나타날 경우 하나로 취급

    % cat > join.data1 98001:서원일: 98002:홍길동: 98003:김유신: 98004:이순신: 98010:이상관: % cat > join.data2 부산:98001:441 울산:98002:89 대구:98003:99 서울:98004:120 김해:98010:44 % join -j1 1 -j2 2 -t: join.data1 join.data2 98001:서원일::부산:441 98002:홍길동::울산:89 98003:김유신::대구:99 98004:이순신::서울:120 98010:이상관::김해:44 % join -j1 1 -j2 2 -o 1.2 1.1 2.1 -t: join.data1 join.data2 서원일:98001:부산 홍길동:98002:울산 김유신:98003:대구 이순신:98004:서울 이상관:98010:김해 %  

    0.0.0.48 파일의 암호화 : crypt

    파일을 암호화 하여 키를 알지 못하는 사람은 내용을 볼 수 없도록 함 표준 입출력 사용
    % cat > crypt.data test test 안녕하십니까? ^D % crypt <crypt.data > crypt.data1 Enter key: hello % ls -l crypt* -rw-r--r-- 1 wiseo pro 24 9월 24일 14:47 crypt.data -rw-r--r-- 1 wiseo pro 24 9월 24일 14:48 crypt.data1 % crypt < crypt.data1 Enter key:hello test test 안녕하십니까? % 

    0.0.0.49 개행을 제외한 화면내의 보이지 않는 문자 출력

    cat -v http://comp-cse.sch.ac.kr/~pl/lecture/linux/file2.html

    0.0.0.50 화일내의 포함된 특정문자열로 찾아서 내용만 출력하기

    grep -h '20030305......01' ./R00*

    0.0.0.51 특정 파일의 화일명을 비슷하게 여러개 한꺼번에 바꾸기

    ls *.* | awk '{print "mv",$1, $1 }' | sed "s/ \([a-zA-Z0-9]*\)\.\([a-zA-Z0-9]*\)$/ \1\.\_\2/g" 
    • 현재디렉토리의 모든 *.* 파일을 *._* 형식으로 바꾼다.
    • 더 간단하게 ls *.* | sed "s/\([a-zA-Z0-9]*\)\.\([a-zA-Z0-9]*\)/mv \1\.\2 \1\.\_\2/g"


    0.0.0.52 어제 날짜 구하기

    $ date -v-1d "+%Y-%m-%d" [컴퓨터분류]

    0.0.0.53 원하지 않는 사용자 죽이기

    [root@dream /root]# skill -KILL sunny

    위의 명령을 내리면 sunny 라는 사용자를 완전히 추방시킬수 있습니다. 그런데 이렇게 완전히 추방시키는게 아니구, 특정 터미널에 접속해있는 사용자만 추방시켜야 할 때도 있겠죠? 그럴때는 [root@dream /root]# skill -KILL -v pts/14

    이런식으로 하면 된다 그럼 pts/14 에 연결되어 있는 사용자가 죽게 됩니다.

    0.0.0.54 UNIX상에서 한글출력이 깨져 나올경우

    유닉스상에서 한글을 stdout출력할 경우 가끔 출력되는 문자들이 몽땅 깨져서 나오는 경우가 있다. 이때부터는 프로그램이 종료된 이후에도 쉘 프람프트를 비롯, 쉘에서 입력하는 모든 커맨드가 깨져서 나온다. 이는 ascii code 로 ^n 에 해당하는 문자가 출력될 때 나오는 현상으로 그 이후로는 MSB가 모두 켜지기 때문이다. 문자가 깨져나오는 이후부터 ascii code 로 ^o 에 해당하는 문자를 출력하면 반대로 된다. 쉘 커맨드 상에서라면, # echo ^v^o

    라고 해야겠지만 커맨드가 깨져나오므로 shell이 해석을 못한다. 따라서, command line에서 ^v^o를 치고 enter 하면 된다

    0.0.0.55 현재 디렉토리의 대량의 파일을 각자의 파일명가운데에 특정문자 추가하여 바꾸기

    /bin/ls A?????.html | sed 's/A\(.....\)\.html/\1/g' | xargs -t -i mv 'A{}.html' 'A0{}.html' 
    /bin/ls는 ls가 보통 -F로 파일 종류 표시(*, @등)까지 하기 때문에 그걸 막기 위한 것이고 xargs의 -t는 트레이스모드이다.
    2006/09/08 22:39 2006/09/08 22:39
    이 글에는 트랙백을 보낼 수 없습니다
    웅쓰:웅자의 상상플러스
    웅자의 상상플러스
    전체 (379)
    게임 (5)
    영화 (2)
    기타 (23)
    맛집 (5)
    영어 (2)
    대수학 (3)
    형태소 (5)
    Hacking (9)
    Linux (112)
    HTML (48)
    Application_developing (48)
    Web_developing (102)
    Window (11)
    «   2024/11   »
              1 2
    3 4 5 6 7 8 9
    10 11 12 13 14 15 16
    17 18 19 20 21 22 23
    24 25 26 27 28 29 30
    1. 2016/01 (1)
    2. 2015/12 (3)
    3. 2015/10 (3)
    4. 2015/03 (2)
    5. 2015/01 (4)