반응형
반응형

'OS > AIX' 카테고리의 다른 글

AIX 5.3 OPENSSH INSTALL  (0) 2011.02.16
bff 파일 설치 (AIX)  (0) 2010.12.08
AIX 5.3에서 Tomcat 설치 및 기본 홈 디렉토리 변경  (1) 2010.12.07
AIX 시스템 점검 쉘  (0) 2010.06.04
Xmanager on AIX 5.3  (1) 2010.02.09
반응형

우선 업무특성상 인터넷 망 영역에서 WAS 시스템이 있어야 한다는 조건이 발생했다....

보안땜시 그렇다고 하는데....

후우...

* 기타 파일들
  - admin 설치용
  - jdk 1.4 호환용

  - 개발자 설치용
  - 전체 document
    - 윈도우 설치용


1. 아래의 사이트에서 톰켓 SRC 버젼을 받는다.
    - 사실 jsp 를 통한 서블릿 과정을 진행할려고 하여 별도의 apache 연동은 없다 ! (웹 서버가 필요하면 별도의 아파치 연동과정을 찾아볼것!)
    - 단순한 한개의 jsp 페이지의 값을 넘겨 주기만 할것임 !
    - 다운로드 주소 : http://tomcat.apache.org/download-55.cgi#5.5.31
- Core부분의 tar.gz을 클릭

2. 클릭하면 저장을 할 수 있다.


3. 설치할 AIX 시스템에 FTP로 전송한다.
    - 계정 root
    - 경로 /usr/local/

4. root 계정으로 쉘 접속을 한다.
    - 아래의 명령을 실행한다.
 # cd /usr/local/
 # gzip -d apache-tomcat-5.5.31.tar.gz
 # tar xvf apache-tomcat-5.5.31.tar
 # ln -s /usr/local/apache-tomcat-5.5.31 /usr/local/tomcat
 # useradd -d /home/tomcat -g staff tomcat
 # passwd tomcat
 # mkdir /home/tomcat
 # chown -R tomcat:staff /usr/local/apache-tomcat-5.5.31 /usr/local/tomcat
 # chown -R tomcat:staff /home/tomcat

5. tomcat 계정으로 접속 후 .profile 파일을 변경처리 한다.

 if [ -s "$MAIL" ]                  # This is at Shell startup.  In normal
        then echo "$MAILMSG"       # operation, the Shell checks
fi                                 # periodically.


export JAVA_HOME=/usr/java5_64

set -o vi

PATH=/usr/bin:/etc:/usr/sbin:/usr/ucb:$HOME/bin:/usr/bin/X11:/sbin:${JAVA_HOME}/jre/bin:${JAVA_HOME}/bin:/usr/local/bin:/usr/local/tomcat/bin:.

stty erase ^?

export LANG=ko_KR

export PS1=[`hostname`:\$PWD]

umask 022


######### Tomcat 환경 변수 등록 #############

export CATALINA_HOME=/usr/local/tomcat


6. 다시 tomcat 계정으로 접속한다.
$> startup.sh 실행 후 (기동 명령)
$> ps -ef | grep startup.sh 조회시 프로세서가 조회되면 정상작동
$> shutdown.sh 실행 후 (종료 명령)
$> ps -ef | grep startup.sh 조회시 프로세서가 조회되지 않아야 정상 종료

위의 startup.sh 실행후 http://서버IP:8080/ 조회하면 노란 고양이를 만날수 있다.

포트 변경은 /usr/local/tomcat/conf/server.xml 파일내의 8080 포트를 검색하여 수정하면 된다(다른 포트와 충돌시 가동하지 않음)

※ 만약 기본 webapps 폴더이외의 홈 경로를 변경하고 싶다면...

/usr/local/tomcat/conf/Catalina/localhost/ROOT.xml 파일 생성

아래의 docBase 내용의 /home/myweb 디렉토리가 홈 디렉토리로 설정된다.

ROOT.xml 파일 내용
 <?xml version="1.0" encoding="UTF-8"?>
<Context path="" docBase="/home/myweb" debug="0" privileged="true" reloadable="true">
<Logger className="org.apache.catalina.logger.FileLogger" directory="logs"  prefix="localhost_log." suffix=".txt" timestamp="true"/>
</Context>



** 보안 취약 사항 수정 방법
telnet 호스트주소 8080
OPTIONS * HTTP/1.0

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Allow: GET, HEAD, POST, PUT, DELETE, OPTIONS
Content-Length: 0
Date: Thu, 23 Jun 2011 08:25:16 GMT
Connection: close

위의 PUT과 DELETE의 불필요한 메소드가 활성화 되어 위험함

제거 방법

/usr/local/tomcat/conf/web.xml 파일 제일 하단부에 붉은 색 표기와 같은 형태로 입력하면 됨

     <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>


 <security-constraint>
 <web-resource-collection>
  <web-resource-name>Protected Context</web-resource-name>
  <url-pattern>/*</url-pattern>
    <http-method>HEAD</http-method>
    <http-method>TRACE</http-method>
    <http-method>OPTIONS</http-method>
 </web-resource-collection>
 <auth-constraint />
 </security-constraint>

   <security-constraint>
     <web-resource-collection>
        <web-resource-name>Protected Context</web-resource-name>
         <url-pattern>/servlet/org.apache.catalina.servlets.DefaultServlet/*</url-pattern>
      </web-resource-collection>
      <!-- auth-constraint goes here if you requre authentication -->
      <user-data-constraint>
         <transport-guarantee>CONFIDENTIAL</transport-guarantee>
      </user-data-constraint>
   </security-constraint>

</web-app>

 




조치 결과
telnet 호스트주소 8080
OPTIONS * HTTP/1.0

HTTP/1.1 403 Forbidden
Server: Apache-Coyote/1.1
Pragma: No-cache
Cache-Control: no-cache
Expires: Thu, 01 Jan 1970 09:00:00 KST
Content-Type: text/html;charset=utf-8
Content-Length: 1108
Date: Thu, 23 Jun 2011 11:07:09 GMT
Connection: close

<html><head><title>Apache Tomcat/5.5.31 - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 403 - Access to the requested resource has been denied</h1><HR size="1" noshade="noshade"><p><b>type</b> Status report</p><p><b>message</b> <u>Access to the requested resource has been denied</u></p><p><b>description</b> <u>Access to the specified resource (Access to the requested resource has been denied) has been forbidden.</u></p><HR size="1" noshade="noshade"><h3>Apache Tomcat/5.5.31</h3></body></html>Connection closed by foreign host.


반응형

'OS > AIX' 카테고리의 다른 글

bff 파일 설치 (AIX)  (0) 2010.12.08
IBM AIX 용 JAVA 다운로드 주소  (0) 2010.12.07
AIX 시스템 점검 쉘  (0) 2010.06.04
Xmanager on AIX 5.3  (1) 2010.02.09
How to install/start/restart the X11 server under AIX  (0) 2010.02.05
반응형

몇일전 NAT를 걸어놨던 외부 IP로 부터 리눅스 시스템이 해킹을 당했다 -_-ㅋ

아놔....

무슨 광고 사이트가 뜨고 침입한 녀석 IP까지 찾았다...

외국 IP이라... 하앍....

오라클 리스너 설정 변경, apache 웹 시스템 적용 등

알수 없는 짓들만 실컷(?) 하고 나갔다....

그래서 간만에 rkhunter를 사용하여 점검중에 있다.

홈페이지 : http://www.rootkit.nl/projects/rootkit_hunter.html
다운로드 : http://sourceforge.net/projects/rkhunter/


* 지원 OS 버젼들... 참고로 내 리눅스는 centos 5.3이었다.

 Supported operating systems
Supported:
- Most Linux distributions
- Most *BSD distributions

Currently unsupported:
- NetBSD

Tested on:
- AIX 4.1.5 / 4.3.3
- ALT Linux
- Aurora Linux
- CentOS 3.1 / 4.0
- Conectiva Linux 6.0
- Debian 3.x
- FreeBSD 4.3 / 4.4 / 4.7 / 4.8 / 4.9 / 4.10
- FreeBSD 5.0 / 5.1 / 5.2 / 5.2.1 / 5.3
- Fedora Core 1 / Core 2 / Core 3
- Gentoo 1.4, 2004.0, 2004.1
- Macintosh OS 10.3.4-10.3.8
- Mandrake 8.1 / 8.2 / 9.0-9.2 / 10.0 / 10.1
- OpenBSD 3.4 / 3.5
- Red Hat Linux 7.0-7.3 / 8 / 9
- Red Hat Enterprise Linux 2.1 / 3.0
- Slackware 9.0 / 9.1 / 10.0 / 10.1
- SME 6.0
- Solaris (SunOS)
- SuSE 7.3 / 8.0-8.2 / 9.0-9.2
- Ubuntu
- Yellow Dog Linux 3.0 / 3.01

Confirmed to work also on:
- CLFS
- DaNix (Debian clone)
- PCLinuxOS
- VectorLinux SOHO 3.2 / 4.0
- CPUBuilders Linux
- Virtuozzo (VPS)





뭐 간단히 /tmp/에 파일을 복사하여 넣고

gzip -d rkhunter-1.3.6.tar.gz (압축 풀고)
tar xvf rkhunter-1.3.6.tar (타르 파일 풀고)


/tmp/rkhunter-1.3.6/ 디렉토리 파일이 풀린다...

뭐. 설치는 어렵지않다.

/tmp/rkhunter-1.3.6/installer.sh --install

/tmp/rkhunter-1.3.6/installer.sh 쉘을 치면 설명이 나온다.... 한번 읽어 보면 좋다.

1. 설치 화면

 # ./installer.sh  --install
Checking system for:
 Rootkit Hunter installer files: found
 A web file download command: wget found
Starting installation:
 Checking installation directory "/usr/local": it exists and is writable.
 Checking installation directories:
  Directory /usr/local/share/doc/rkhunter-1.3.6: creating: OK
  Directory /usr/local/share/man/man8: exists and is writable.
  Directory /etc: exists and is writable.
  Directory /usr/local/bin: exists and is writable.
  Directory /usr/local/lib64: exists and is writable.
  Directory /var/lib: exists and is writable.
  Directory /usr/local/lib64/rkhunter/scripts: creating: OK
  Directory /var/lib/rkhunter/db: creating: OK
  Directory /var/lib/rkhunter/tmp: creating: OK
  Directory /var/lib/rkhunter/db/i18n: creating: OK
 Installing check_modules.pl: OK
 Installing filehashmd5.pl: OK
 Installing filehashsha1.pl: OK
 Installing filehashsha.pl: OK
 Installing stat.pl: OK
 Installing readlink.sh: OK
 Installing backdoorports.dat: OK
 Installing mirrors.dat: OK
 Installing programs_bad.dat: OK
 Installing suspscan.dat: OK
 Installing rkhunter.8: OK
 Installing ACKNOWLEDGMENTS: OK
 Installing CHANGELOG: OK
 Installing FAQ: OK
 Installing LICENSE: OK
 Installing README: OK
 Installing language support files: OK
 Installing rkhunter: OK
 Installing rkhunter.conf: OK
Installation complete

2. 위의 정상적으로 설치 완료 화면을 보고 난뒤
    /usr/local/bin/rkhunter 폴더를 볼수 있다.
    - 실행해 보기

 # ./rkhunter

Usage: rkhunter {--check | --unlock | --update | --versioncheck |
                 --propupd [{filename | directory | package name},...] |
                 --list [{tests | {lang | languages} | rootkits}] |
                 --version | --help} [options]

Current options are:
         --append-log                  Append to the logfile, do not overwrite
         --bindir <directory>...       Use the specified command directories
     -c, --check                       Check the local system
  --cs2, --color-set2                  Use the second color set for output
         --configfile <file>           Use the specified configuration file
         --cronjob                     Run as a cron job
                                       (implies -c, --sk and --nocolors options)
         --dbdir <directory>           Use the specified database directory
         --debug                       Debug mode
                                       (Do not use unless asked to do so)
         --disable <test>[,<test>...]  Disable specific tests
                                       (Default is to disable no tests)
         --display-logfile             Display the logfile at the end
         --enable  <test>[,<test>...]  Enable specific tests
                                       (Default is to enable all tests)
         --hash {MD5 | SHA1 | SHA224 | SHA256 | SHA384 | SHA512 |
                 NONE | <command>}     Use the specified file hash function
                                       (Default is SHA1, then MD5)
     -h, --help                        Display this help menu, then exit
 --lang, --language <language>         Specify the language to use
                                       (Default is English)
         --list [tests | languages |   List the available test names, languages,
                 rootkits]             or checked for rootkits, then exit
     -l, --logfile [file]              Write to a logfile
                                       (Default is /var/log/rkhunter.log)
         --noappend-log                Do not append to the logfile, overwrite it
         --nocolors                    Use black and white output
         --nolog                       Do not write to a logfile
--nomow, --no-mail-on-warning          Do not send a message if warnings occur
   --ns, --nosummary                   Do not show the summary of check results
 --novl, --no-verbose-logging          No verbose logging
         --pkgmgr {RPM | DPKG | BSD |  Use the specified package manager to obtain or
                   NONE}               verify file hash values. (Default is NONE)
         --propupd [file | directory | Update the entire file properties database,
                    package]...        or just for the specified entries
     -q, --quiet                       Quiet mode (no output at all)
  --rwo, --report-warnings-only        Show only warning messages
     -r, --rootdir <directory>         Use the specified root directory
   --sk, --skip-keypress               Don't wait for a keypress after each test
         --summary                     Show the summary of system check results
                                       (This is the default)
         --syslog [facility.priority]  Log the check start and finish times to syslog
                                       (Default level is authpriv.notice)
         --tmpdir <directory>          Use the specified temporary directory
         --unlock                      Unlock (remove) the lock file
         --update                      Check for updates to database files
   --vl, --verbose-logging             Use verbose logging (on by default)
     -V, --version                     Display the version number, then exit
         --versioncheck                Check for latest version of program
     -x, --autox                       Automatically detect if X is in use
     -X, --no-autox                    Do not automatically detect if X is in use


헉스,,, 옵션을 줘야 한다.

처음에는 rkhunter가 사용하는 DB부터 만들어주는것을 권고한다.

# rkhunter --propupd

끝나면

실제로 check를 해보자

# rhunter -c

실행화면 (칼라로 나온다 잇힝...)

 [ Rootkit Hunter version 1.3.6 ]

Checking system commands...

  Performing 'strings' command checks
    Checking 'strings' command                               [ OK ]

  Performing 'shared libraries' checks
    Checking for preloading variables                        [ None found ]
    Checking for preloaded libraries                         [ None found ]
    Checking LD_LIBRARY_PATH variable                        [ Not found ]

  Performing file properties checks
    Checking for prerequisites                               [ OK ]
    /bin/awk                                                 [ Warning ]
    /bin/basename                                            [ OK ]
    /bin/bash                                                [ OK ]
    /bin/cat                                                 [ OK ]
    /bin/chmod                                               [ OK ]
    /bin/chown                                               [ OK ]
    /bin/cp                                                  [ OK ]
    /bin/csh                                                 [ OK ]
    /bin/cut                                                 [ OK ]
    /bin/date                                                [ OK ]
    /bin/df                                                  [ OK ]
    /bin/dmesg                                               [ OK ]
    /bin/echo                                                [ OK ]
    /bin/ed                                                  [ OK ]
    /bin/egrep                                               [ OK ]
    /bin/env                                                 [ OK ]
    /bin/fgrep                                               [ OK ]
    /bin/grep                                                [ OK ]
    /bin/kill                                                [ OK ]
    /bin/logger                                              [ OK ]
    /bin/login                                               [ OK ]
    /bin/ls                                                  [ OK ]
    /bin/mail                                                [ OK ]
    /bin/mktemp                                              [ OK ]
    /bin/more                                                [ OK ]
    /bin/mount                                               [ OK ]
    /bin/mv                                                  [ OK ]
    /bin/netstat                                             [ OK ]
    /bin/ps                                                  [ OK ]
    /bin/pwd                                                 [ OK ]
    /bin/rpm                                                 [ Warning ]
    /bin/sed                                                 [ OK ]
    /bin/sh                                                  [ OK ]
    /bin/sort                                                [ OK ]
    /bin/su                                                  [ OK ]
    /bin/touch                                               [ OK ]
    /bin/uname                                               [ OK ]
    /bin/gawk                                                [ Warning ]
    /bin/tcsh                                                [ OK ]
    /usr/bin/awk                                             [ Warning ]
    /usr/bin/chattr                                          [ OK ]
    /usr/bin/curl                                            [ Warning ]
    /usr/bin/cut                                             [ OK ]
    /usr/bin/diff                                            [ OK ]
    /usr/bin/dirname                                         [ OK ]
    /usr/bin/du                                              [ OK ]
    /usr/bin/elinks                                          [ Warning ]
    /usr/bin/env                                             [ OK ]
    /usr/bin/file                                            [ OK ]
    /usr/bin/find                                            [ OK ]
    /usr/bin/groups                                          [ Warning ]
    /usr/bin/head                                            [ OK ]
    /usr/bin/id                                              [ OK ]
    /usr/bin/kill                                            [ OK ]
    /usr/bin/killall                                         [ OK ]
    /usr/bin/last                                            [ OK ]
    /usr/bin/lastlog                                         [ OK ]
    /usr/bin/ldd                                             [ Warning ]
    /usr/bin/less                                            [ OK ]
    /usr/bin/links                                           [ Warning ]
    /usr/bin/locate                                          [ OK ]
    /usr/bin/logger                                          [ OK ]
    /usr/bin/lsattr                                          [ OK ]
    /usr/bin/md5sum                                          [ OK ]
    /usr/bin/newgrp                                          [ OK ]
    /usr/bin/passwd                                          [ OK ]
    /usr/bin/perl                                            [ Warning ]
    /usr/bin/pgrep                                           [ OK ]
    /usr/bin/pstree                                          [ OK ]
    /usr/bin/readlink                                        [ OK ]
    /usr/bin/runcon                                          [ OK ]
    /usr/bin/sha1sum                                         [ OK ]
    /usr/bin/sha224sum                                       [ OK ]
    /usr/bin/sha256sum                                       [ OK ]
    /usr/bin/sha384sum                                       [ OK ]
    /usr/bin/sha512sum                                       [ OK ]
    /usr/bin/size                                            [ OK ]
    /usr/bin/stat                                            [ OK ]
    /usr/bin/strings                                         [ OK ]
    /usr/bin/sudo                                            [ OK ]
    /usr/bin/tail                                            [ OK ]
    /usr/bin/test                                            [ OK ]
    /usr/bin/top                                             [ OK ]
    /usr/bin/tr                                              [ OK ]
    /usr/bin/uniq                                            [ OK ]
    /usr/bin/users                                           [ OK ]
    /usr/bin/vmstat                                          [ OK ]
    /usr/bin/w                                               [ OK ]
    /usr/bin/watch                                           [ OK ]
    /usr/bin/wc                                              [ OK ]
    /usr/bin/wget                                            [ OK ]
    /usr/bin/whatis                                          [ Warning ]
    /usr/bin/whereis                                         [ OK ]
    /usr/bin/which                                           [ OK ]
    /usr/bin/who                                             [ OK ]
    /usr/bin/whoami                                          [ OK ]
    /usr/bin/gawk                                            [ Warning ]
    /sbin/chkconfig                                          [ OK ]
    /sbin/depmod                                             [ OK ]
    /sbin/fuser                                              [ OK ]
    /sbin/ifconfig                                           [ OK ]
    /sbin/ifdown                                             [ Warning ]
    /sbin/ifup                                               [ Warning ]
    /sbin/init                                               [ OK ]
    /sbin/insmod                                             [ OK ]
    /sbin/ip                                                 [ OK ]
    /sbin/kudzu                                              [ OK ]
    /sbin/lsmod                                              [ OK ]
    /sbin/modinfo                                            [ OK ]
    /sbin/modprobe                                           [ OK ]
    /sbin/nologin                                            [ OK ]
    /sbin/rmmod                                              [ OK ]
    /sbin/runlevel                                           [ OK ]
    /sbin/sulogin                                            [ OK ]
    /sbin/sysctl                                             [ OK ]
    /sbin/syslogd                                            [ OK ]
    /usr/sbin/adduser                                        [ OK ]
    /usr/sbin/chroot                                         [ OK ]
    /usr/sbin/groupadd                                       [ OK ]
    /usr/sbin/groupdel                                       [ OK ]
    /usr/sbin/groupmod                                       [ OK ]
    /usr/sbin/grpck                                          [ OK ]
    /usr/sbin/kudzu                                          [ OK ]
    /usr/sbin/lsof                                           [ OK ]
    /usr/sbin/prelink                                        [ OK ]
    /usr/sbin/pwck                                           [ OK ]
    /usr/sbin/sestatus                                       [ OK ]
    /usr/sbin/tcpd                                           [ OK ]
    /usr/sbin/useradd                                        [ OK ]
    /usr/sbin/userdel                                        [ OK ]
    /usr/sbin/usermod                                        [ OK ]
    /usr/sbin/vipw                                           [ OK ]
    /usr/local/bin/rkhunter                                  [ OK ]
    /etc/rkhunter.conf                                       [ OK ]

[Press <ENTER> to continue]


Checking for rootkits...

  Performing check of known rootkit files and directories
    55808 Trojan - Variant A                                 [ Not found ]
    ADM Worm                                                 [ Not found ]
    AjaKit Rootkit                                           [ Not found ]
    Adore Rootkit                                            [ Not found ]
    aPa Kit                                                  [ Not found ]
    Apache Worm                                              [ Not found ]
    Ambient (ark) Rootkit                                    [ Not found ]
    Balaur Rootkit                                           [ Not found ]
    BeastKit Rootkit                                         [ Not found ]
    beX2 Rootkit                                             [ Not found ]
    BOBKit Rootkit                                           [ Not found ]
    cb Rootkit                                               [ Not found ]
    CiNIK Worm (Slapper.B variant)                           [ Not found ]
    Danny-Boy's Abuse Kit                                    [ Not found ]
    Devil RootKit                                            [ Not found ]
    Dica-Kit Rootkit                                         [ Not found ]
    Dreams Rootkit                                           [ Not found ]
    Duarawkz Rootkit                                         [ Not found ]
    Enye LKM                                                 [ Not found ]
    Flea Linux Rootkit                                       [ Not found ]
    FreeBSD Rootkit                                          [ Not found ]
    Fu Rootkit                                               [ Not found ]
    Fuck`it Rootkit                                          [ Not found ]
    GasKit Rootkit                                           [ Not found ]
    Heroin LKM                                               [ Not found ]
    HjC Kit                                                  [ Not found ]
    ignoKit Rootkit                                          [ Not found ]
    iLLogiC Rootkit                                          [ Not found ]
    IntoXonia-NG Rootkit                                     [ Not found ]
    Irix Rootkit                                             [ Not found ]
    Kitko Rootkit                                            [ Not found ]
    Knark Rootkit                                            [ Not found ]
    ld-linuxv.so Rootkit                                     [ Not found ]
    Li0n Worm                                                [ Not found ]
    Lockit / LJK2 Rootkit                                    [ Not found ]
    Mood-NT Rootkit                                          [ Not found ]
    MRK Rootkit                                              [ Not found ]
    Ni0 Rootkit                                              [ Not found ]
    Ohhara Rootkit                                           [ Not found ]
    Optic Kit (Tux) Worm                                     [ Not found ]
    Oz Rootkit                                               [ Not found ]
    Phalanx Rootkit                                          [ Not found ]
    Phalanx2 Rootkit                                         [ Not found ]
    Phalanx2 Rootkit (extended tests)                        [ Not found ]
    Portacelo Rootkit                                        [ Not found ]
    R3dstorm Toolkit                                         [ Not found ]
    RH-Sharpe's Rootkit                                      [ Not found ]
    RSHA's Rootkit                                           [ Not found ]
    Scalper Worm                                             [ Not found ]
    Sebek LKM                                                [ Not found ]
    Shutdown Rootkit                                         [ Not found ]
    SHV4 Rootkit                                             [ Not found ]
    SHV5 Rootkit                                             [ Not found ]
    Sin Rootkit                                              [ Not found ]
    Slapper Worm                                             [ Not found ]
    Sneakin Rootkit                                          [ Not found ]
    'Spanish' Rootkit                                        [ Not found ]
    Suckit Rootkit                                           [ Not found ]
    SunOS Rootkit                                            [ Not found ]
    SunOS / NSDAP Rootkit                                    [ Not found ]
    Superkit Rootkit                                         [ Not found ]
    TBD (Telnet BackDoor)                                    [ Not found ]
    TeLeKiT Rootkit                                          [ Not found ]
    T0rn Rootkit                                             [ Not found ]
    trNkit Rootkit                                           [ Not found ]
    Trojanit Kit                                             [ Not found ]
    Tuxtendo Rootkit                                         [ Not found ]
    URK Rootkit                                              [ Not found ]
    Vampire Rootkit                                          [ Not found ]
    VcKit Rootkit                                            [ Not found ]
    Volc Rootkit                                             [ Not found ]
    Xzibit Rootkit                                           [ Not found ]
    X-Org SunOS Rootkit                                      [ Not found ]
    zaRwT.KiT Rootkit                                        [ Not found ]
    ZK Rootkit                                               [ Not found ]

  Performing additional rootkit checks
    Suckit Rookit additional checks                          [ OK ]
    Checking for possible rootkit files and directories      [ None found ]
    Checking for possible rootkit strings                    [ None found ]

  Performing malware checks
    Checking running processes for suspicious files          [ None found ]
    Checking for login backdoors                             [ None found ]
    Checking for suspicious directories                      [ None found ]
    Checking for sniffer log files                           [ None found ]
    Checking for Apache backdoor                             [ Not found ]

  Performing Linux specific checks
    Checking loaded kernel modules                           [ OK ]
    Checking kernel module names                             [ OK ]

[Press <ENTER> to continue]


Checking the network...

  Performing check for backdoor ports
    Checking for TCP port 1524                               [ Not found ]
    Checking for TCP port 1984                               [ Not found ]
    Checking for UDP port 2001                               [ Not found ]
    Checking for TCP port 2006                               [ Not found ]
    Checking for TCP port 2128                               [ Not found ]
    Checking for TCP port 6666                               [ Not found ]
    Checking for TCP port 6667                               [ Not found ]
    Checking for TCP port 6668                               [ Not found ]
    Checking for TCP port 6669                               [ Not found ]
    Checking for TCP port 7000                               [ Not found ]
    Checking for TCP port 13000                              [ Not found ]
    Checking for TCP port 14856                              [ Not found ]
    Checking for TCP port 25000                              [ Not found ]
    Checking for TCP port 29812                              [ Not found ]
    Checking for TCP port 31337                              [ Not found ]
    Checking for TCP port 33369                              [ Not found ]
    Checking for TCP port 47107                              [ Not found ]
    Checking for TCP port 47018                              [ Not found ]
    Checking for TCP port 60922                              [ Not found ]
    Checking for TCP port 62883                              [ Not found ]
    Checking for TCP port 65535                              [ Not found ]

  Performing checks on the network interfaces
    Checking for promiscuous interfaces                      [ None found ]

[Press <ENTER> to continue]


Checking the local host...

  Performing system boot checks
    Checking for local host name                             [ Found ]
    Checking for system startup files                        [ Found ]
    Checking system startup files for malware                [ None found ]

  Performing group and account checks
    Checking for passwd file                                 [ Found ]
    Checking for root equivalent (UID 0) accounts            [ Warning ]
    Checking for passwordless accounts                       [ None found ]
    Checking for passwd file changes                         [ None found ]
    Checking for group file changes                          [ None found ]
    Checking root account shell history files                [ OK ]

  Performing system configuration file checks
    Checking for SSH configuration file                      [ Found ]
    Checking if SSH root access is allowed                   [ Warning ]
    Checking if SSH protocol v1 is allowed                   [ Not allowed ]
    Checking for running syslog daemon                       [ Found ]
    Checking for syslog configuration file                   [ Found ]
    Checking if syslog remote logging is allowed             [ Not allowed ]

  Performing filesystem checks
    Checking /dev for suspicious file types                  [ None found ]
    Checking for hidden files and directories                [ Warning ]

[Press <ENTER> to continue]


Checking application versions...

    Checking version of GnuPG                                [ OK ]
    Checking version of Apache                               [ Warning ]
    Checking version of OpenSSL                              [ Warning ]
    Checking version of PHP                                  [ Warning ]
    Checking version of Procmail MTA                         [ OK ]
    Checking version of OpenSSH                              [ Warning ]


System checks summary
=====================

File properties checks...
    Files checked: 134
    Suspect files: 14

Rootkit checks...
    Rootkits checked : 253
    Possible rootkits: 0

Applications checks...
    Applications checked: 6
    Suspect applications: 4

The system checks took: 1 minute and 56 seconds

All results have been written to the log file (/var/log/rkhunter.log)

One or more warnings have been found while checking the system.
Please check the log file (/var/log/rkhunter.log)

 



자 끝났다... 실제 체크 옵션의 Warning 부분인데.. 어라.. 자세히 안나온다

자세한 내용은 /var/log/rkhunter.log를 살펴보자... 그럼 더 자세한 경고 문구들이 나온다.

조치방법은 워낙 많기 때문에 구글링(www.google.co.kr)을 통해 검색해 보자 ~

하앍.............
반응형

'OS > Linux' 카테고리의 다른 글

CENTOS 7에 XRDP 설치하기  (0) 2017.08.26
리눅스 백업 및 복구  (0) 2013.01.25
삼성 컴퓨터 유분투 설치기.  (0) 2012.02.06
ps auxc 와 ps aux 결과 비교하기  (0) 2010.01.21
AWK & SED chunk_1  (0) 2010.01.21
반응형

어느날 갑자기... PUTTY로 접속을 하려는데

다음과 같은 에러를 발생하며 접속이 안된다...

물론 id / password를 다 넣었다.

Server unexpectedly closed network connection

서버로 네트워크 연결이 예상지 못하게 종료되었습니다.

라는 뜻인데...

우선 로그를 살펴보았다.

/var/log/secure

 pam_unix(sshd:session): session opened for user test01 by test01(uid=100)
 pam_loginuid(sshd:session): set_loginuid failed opening loginuid
 pam_loginuid(sshd:session): set_loginuid failed

로그를보면 test01이라는 계정이 set_loginuid 의 열기 실패했다고 볼수 있다.

관련 내용을 구글링을 통해 검색해 보았다.

Server unexpectedly closed network connection

-> 즉 2가지 수정안인데... 나와 같이 특정계정만 막힌 경우는 해결되지 않았다.

 Server unexpectedly closed network connection"

라는 에러 메시지와 함께 접속 안 되는 경우가 생깁니다

그럴 경우에는 /etc/ssh/sshd_config 에서 UseDNS no 라고 추가 시켜 준 다음에

ssh 데몬(sshd)를 재시작(하거나 kill 로 죽인 다음에 다시 실행)하면 됩니다

추가
이전 키는 삭제 해야 합니다

리눅스에서는 ~계졍명/.ssh/known_hosts 에 해당하는 주소에 키를 삭제 하면 되고

윈도우에서 putty를 쓸 경우에는 레지스트리에서
HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys
에 해당하는 키를 삭제하면 됩니다--moon.ft.co.kr

출처 : http://www.hostingland.co.kr/service/memo_view.htm?mode=view&code=memo&kind=h_qna&num=140448&idx_num=198

그러다가 로그의 내용을 중심으로 다시 구글링을 해보았다.

그랬더니 centos의 일종의 버그였다.

# grep pam_loginuid.so /etc/pam.d/*

/etc/pam.d/crond:session required pam_loginuid.so
/etc/pam.d/login:session required pam_loginuid.so
/etc/pam.d/remote:session required pam_loginuid.so
/etc/pam.d/sshd:session required pam_loginuid.so

위의 내용중 제일 하단에 결과를 보면 /etc/pam.d/sshd 파일의 세션 정보에서 pam_loguid.so를 사용함을 알수 있다.

즉, ssh를 통한 접속시 pam_loginuid를 이용하는 것을 알수 있다.

이부분을 # 처리하고

# service restart sshd

명령을 통해 sshd를 재시작하면 정상적으로 접속이 된다.

출처 : http://forums.powervps.com/showthread.php?p=19872

위의 출처를 통해 가보면 로그인을 통한 메모리 이득을 취할 수 있다고 하는데...

더 분석을 해봐야 겠다...
반응형
반응형

보안 위배 사항을 나열해 주는 점검쉘...

대기업에서 만든 버젼인데...

유출을 걱정했는지,

분석구분은 안들어있고

조회만 하넹...

걍 내가 만든게 더 나을꺼 같다 -_-;

반응형
반응형


아래의 글 참고

How to install/start/restart the X11 server under AIX

기본적으로

lssrc -s dtsrc 명령(root로 실행)을 실행 했을 때 actvie 상태여야만 한다.

1. hosts 파일 세팅
   서버 PC의 /etc/hosts 파일에 접속할 IP정보를 추가한다.
   예) 접속할 IP : 100.1.1.10 
   100.1.1.10       client_pc
  

2. ping TEST 수행
   #> ping client_pc 했을 때 정상적으로 조회된다면 문제가 없으나 대부분의 경우는 이부분에서 문제가 발생함...
       즉 실제로는 100.1.1.10 IP가 조회되어야 하나 이상한 IP로 조회되는 경우가 있음.
        문제는 DNS 정보를 서버의 hosts 파일보다 먼저 찾기 때문에 발생
        아래와 같이 수정 가능
       /etc/netsvc.conf 파일을 수정
       제일 아래줄에 
       hosts=local,bind 로 추가
반응형
반응형

Now, this one was pretty frustrating, especially with a DBA demanding X11 access to an AIX server so that he could install on it...

Here is how to do it:

1. Check that the X11 server is installed

This can be done with the following command:

# lslpp -l | grep -i X11.Dt

If X11 is installed on an AIX machine, the above command should return (more or less):

andre@galactus$ lslpp -l | grep -i x11.dt
  X11.Dt.ToolTalk           5.3.0.60  COMMITTED     AIX CDE ToolTalk Support
  X11.Dt.bitmaps             5.3.0.0  COMMITTED     AIX CDE Bitmaps
  X11.Dt.helpmin             5.3.0.0  COMMITTED     AIX CDE Minimum Help Files
  X11.Dt.helprun             5.3.0.0  COMMITTED     AIX CDE Runtime Help
  X11.Dt.lib                5.3.0.60  COMMITTED     AIX CDE Runtime Libraries
  X11.Dt.rte                5.3.0.60  COMMITTED     AIX Common Desktop Environment
  X11.Dt.ToolTalk           5.3.0.60  COMMITTED     AIX CDE ToolTalk Support
  X11.Dt.bitmaps             5.3.0.0  COMMITTED     AIX CDE Bitmaps
  X11.Dt.helpmin             5.3.0.0  COMMITTED     AIX CDE Minimum Help Files
  X11.Dt.rte                5.3.0.60  COMMITTED     AIX Common Desktop Environment

If not, you need to install the X11 server. See below.

2. Installing the X11 server on an AIX machine

The X11 packages are on the #2 AIX installation CD, in the /installp/ppc/ directory.

To search for the proper package, once the CD has been installed in the CD-ROM drive of your AIX machine, you can issue the following commands:

# find /cdrom1 -name *dt* /cdrom1/installp/ppc/X11.adt /cdrom1/usr/sys/inst.images/X11.adt

Here, of course, the CD-ROM drive is mounted under /cdrom1.

If we list this directory, here is the content:

# cd /cdrom1/installp/ppc/
# ls
.toc                     X11.help.en_US           csm.gui.dcem_1.6.0.10
Java14.license           X11.loc.en_US            invscout.websm
Java14.sdk               X11.man.en_US            sysmgt.help.en_US
Java5.sdk                X11.motif                sysmgt.help.msg.en_US
X11.Dt                   X11.msg.en_US            sysmgt.msg.en_US.sguide
X11.Dt.other             X11.samples              sysmgt.msg.en_US.websm
X11.adt                  X11.vfb                  sysmgt.sguide
X11.apps                 X11.vsm                  sysmgt.websm
X11.base                 bos.aixpert              sysmgt.websm.diskarray
X11.compat.X11R5         bos.ecc_client           sysmgtlib.framework
X11.compat.other         bos.installers           sysmgtlib.libraries
X11.fnt                  csm.gui.dcem

Now, to install with smitty, type smitty as root, and go to "Software installation > Install software".

Next, select your CD-ROM device, and check the following configuration is correct:

                                Install Software

Type or select values in entry fields.       
Press Enter AFTER making all desired changes.

                                                        [Entry Fields]
* INPUT device / directory for software               /dev/cd1
* SOFTWARE to install                                [+ 5.3.0.60  AIX CDE A> +
  PREVIEW only? (install operation will NOT occur)    no                     +
  COMMIT software updates?                            yes                    +
  SAVE replaced files?                                no                     +
  AUTOMATICALLY install requisite software?           yes                    +
  EXTEND file systems if space needed?                yes                    +
  OVERWRITE same or newer versions?                   no                     +
  VERIFY install and check file sizes?                yes                    +
  Include corresponding LANGUAGE filesets?            yes                    +
  DETAILED output?                                    yes                    +
  Process multiple volumes?                           yes                    +
  ACCEPT new license agreements?                      yes                    + 
  PREVIEW new LICENSE agreements?                     no                     +

F1=Help             F2=Refresh          F3=Cancel           F4=List
F5=Reset            F6=Command          F7=Edit             F8=Image
F9=Shell            F10=Exit            Enter=Do                    

In the SOFTWARE to install, press "F4" (=List) and select all the CDE packages, using the list of packages above as a guide.

Next, press ENTER and the installation should proceed correctly.

3. How to start the X11 server

There are several possibilities here. Please keep in mind that I was trying to have a minimal X11 server, to allow one user to connect. I was not so much interested in correctness...

Two possibilities:

  • Use the dtlogin command as shown below:
# /usr/dt/bin/dtlogin -daemon
  • Use the /etc/rc.dt script as shown below:
# /etc/rc.dt

This script has the advantage of launching a full X11 environment, including a login prompt on the console.

In both cases, you can check the X11 server is running correctly with the following command:

andre@galactus$ ps -fe | grep -i dtlogin | grep -v grep root 94310 1 0 26 sep - 0:00 /usr/dt/bin/dtlogin -daemon root 147544 94310 0 26 sep - 0:00 dtlogin <:0> -daemon

4. Restart X11 in case of a crash or a misbehaving server

Please make sure you go through the entire list. This is a bit tedious, but it works very well, so make sure you go through all the steps and don't try to skip one...

  • Stop all "rc.bootx" processes:
# ps -fe | grep -i rc.bootx # kill -9 <rc.bootx PIDs>

WARNING: If there are ANY "rc.bootx" processes, they MUST be stopped before anything else!

  • Stop all "dtlogin" processes:
# ps -fe | grep -i dtlogin # kill -9 <dtlogin PIDs>

WARNING: Make sure there are no processes attached to the "dtlogin" processes...

  • Delete all temporary files:
cd /var/dt rm Xerrors rm Xpid

Sometimes, it could be interesting to keep a copy of the Xerrors file...

  • Check available space under /var and /tmp:

For instance:

-bash-3.00$ df -g /var /tmp Filesystem GB blocks Free %Used Iused %Iused Mounted on /dev/hd9var 1.02 0.29 72% 556 1% /var /dev/hd3 3.05 2.28 26% 1726 1% /tmp

This space-checking stage is optional, but you never know... :-)

  • Check that the "dtsrc" service is inoperative:

Do this with the following command:

$ lssrc -s dtsrc Subsystem Group PID Status dtsrc inoperative
  • Restart the service with "/etc/rc.dt" :
# /etc/rc.dt
  • Check that the "dtlogin" service is running:
bash-2.05b$ ps -fe | grep -i dtlogin | grep -v grep root 65704 1 0 Sep 09 - 0:00 /usr/dt/bin/dtlogin -daemon root 74118 65704 0 Sep 09 - 0:00 dtlogin <:0> -daemon
  • Check that the service is marked as "active":
bash-2.05b$ lssrc -s dtsrc Subsystem Group PID Status dtsrc active

See Also:


 출처 : http://www.gilandre.net/cgi-bin/wiki.cgi/AIXServerX11

반응형
반응형

#echo $ODMDIR /etc/objrepos에 있어야 함

# odmget -q attribute=route CuAt  <- 여기에 route 정보들을 가진 ODM stanza가 나열됨.

## 아래 예 ##
CuAt:
        name = "inet0"
        attribute = "route"
        value = "net,-hopcount,0,,0,165.244.227.1"
        type = "R"
        generic = "DU"
        rep = "s"
        nls_index = 0

CuAt:
        name = "inet0"
        attribute = "route"
        value = "net,-hopcount,0,,0,165.244.226.1"
        type = "R"
        generic = "DU"
        rep = "s"
        nls_index = 0

해당하는 default gateway를 반드시 확인하고 잘못된 route 정보들을 ODM에서 지우기 위해서는

#  odmget -q attribute=route CuAt  에서 나온 정보 중 value 값을 copy 해서 지웁니다.

value 부분을 쓸때는 따옴표를 주의

#  odmdelete -q "value=net,-hopcount,0,,0,165.244.226.1" -o CuAt

0518-307 odmdelete: 1 objects deleted.


정확히 확인을 위해서 다시 odmget을 통하여 default value 확인

# odmget -q attribute=route CuAt 

CuAt:
        name = "inet0"
        attribute = "route"
        value = "net,-hopcount,0,,0,165.244.227.1"
        type = "R"
        generic = "DU"
        rep = "s"
        nls_index = 0
#

마지막으로 netstat -nr을 통하여 route 정보 확인
여기서는 route delete option을 통하여 삭제

반응형
반응형

ps auxc와 ps aux를 비교해서 수상쩍은 프로세스를 감시할 수도 있다. 이 작업을 편하게 하기 위해 스크립트를 만들었다. 아래 내용을 복사해서 셸 스크립트를 작성한다.

#!/bin/bash
temp1=`mktemp`;
temp2=`mktemp`;

/bin/ps auxc |awk 'NR != 1{for (i = 11; i<=NF; i++) a=a" "$i; print $2,$1,a; a=""}'|sort -n > $temp1
/bin/ps aux |awk 'NR != 1{for (i = 11; i<=NF; i++) a=a" "$i; print $2,$1,a; a=""}'|sort -n > $temp2

echo -e "ps auxc\nps aux"
awk '
{
if (!a[$1]) {
for (i=2; i<=NF;i++){
p = p" "$i;
}
a[$1] = a[$1]" "p;
indexes[CNT++] = $1;
p = "";
} else {
len = length($1);
blank = " ";
for (i=0; i<len; i++){
blank = blank" ";
}
a[$1] = a[$1]"\n"blank;
for (i = 2; i<=NF;i++){
p = p" "$i
}
a[$1] = a[$1]" "p;
p = "";

}
} END {
for (i=0;i<CNT;i++) {
print indexes[i],a[indexes[i]];
}
}' $temp1 $temp2



rm $temp1 $temp2

출처 : http://rhdxmr.tistory.com/60
반응형

'OS > Linux' 카테고리의 다른 글

CENTOS 7에 XRDP 설치하기  (0) 2017.08.26
리눅스 백업 및 복구  (0) 2013.01.25
삼성 컴퓨터 유분투 설치기.  (0) 2012.02.06
rkhunter (리눅스 침입 탐지 사용하기)  (1) 2010.10.14
AWK & SED chunk_1  (0) 2010.01.21
반응형
 
AWK와 SED는 비슷한 또래의 사촌이다. 유닉스 초창기에 개발됐고 훌륭한 기능을 제공하므로 1979년 이후 다양한 유닉스 변종들과 유닉스-like 운영체제에 꼭 포함돼 많은 사랑을 받아왔다. 둘이 맡은 역할은 텍스트 프로세싱이다. 유닉스 프로그램들은 데이터를 일반 텍스트 파일로 저장하는 경우가 많기 때문에 유닉스 환경에서 AWK와 SED를 활용함으로써 처리할 수 있는 작업은 종류를 셀 수 없을 것이다. 게다가 파이프라인이 가능하므로 표준 출력을 AWK와 SED의 표준 입력으로 받아 처리 할 수 있으므로 텍스트가 들어가는 모든 작업에 사용될 수 있다해도 과언은 아니다. 이 둘은 헤아릴 수 없이 많이 카피돼 지난 한 세대 동안 메인프레임이나 대형 서버에서 프로세스로서 숨쉬어왔다. 하지만 80년대 중반에 더 강력한 기능을 제공하는 펄이 등장했고 그후로 AWK와 SED의 인기는 점점 사그라들었다. 게다가 AWK와 SED의 스크립트를 작성하기도 해석하기도 어렵기 때문에 조금이라도 복잡한 스크립트를 프로그래밍할 필요가 생기면 펄이나 파이썬을 추천하는 추세다. 

그러나 더 강력한 기능과 더 나은 개발 용이성을 제공하는 언어의 등장에도 불구하고 AWK와 SED는
30년 넘게 살아남았다. 대체 그 이유가 뭘까? 유닉스 초창기에 대한 향수 때문에 올드 프로그래머들이 사용하는 걸까? 아니면 복잡한 프로그래밍을 즐기는 소수 마니아들이 끈질기게 그 둘을 놓지 않기 때문일까? 아마 직접 써보면 알게 될 것이다.


이 문서의 목적
AWK와 SED에 처음 발을 들여놓는 사람들을 위한 가이드라인이다. AWK나 SED의 모든 기능을 다루지는 않았고, 문서 곳곳에서 '그밖의 내용은 맨페이지를 참고하라'는 식의 말이 나온다. AWK와 SED에 필수적인 내용을 조감하기 위함이다.

현재 문서 버전

2009년 11월 24일 버전 <- 현재
2009년 11월 21일 버전

AWK와 SED는 사용하기 어렵다?
많은 이들이 AWK와 SED로 작성된 스크립트를 보고 해석하기 난해해 하는 이유는 많은 사용자들이 AWK와 SED가 프로그래밍 언어인지 모르기 때문이라 생각한다. 사용방법이 비교적 간단해서 금방 배울 수 있는 유틸리티와 혼동하여 "AWK나 SED도 유틸리티인데 이걸 공부할 필요까진 없다" 라고 착각하기 때문에, 유틸리티 치고는 AWK와 SED 는 어렵다고 손사래 치는 것이다. 그러나 AWK나 SED도 엄연히 프로그래밍 언어고 어느 정도의 지식이 있어야 사용할 수 있다. 하지만 언어치고는 습득에 걸리는 시간이 길지 않고, 이 짧은 문서에 많은 내용을 담을 수 있을만큼 알아야할 것이 많지 않기 때문에 어려울 거란 염려는 넣어두시라. ;)

작성자
정준영; 이 문서는 2009년 11월, 한주마다 열리는 HLUG 내부 세미나를 위한 발표자료를 토대로 작성하였다.

목차
I. AWK & SED 역사적 배경 (이 포스트에서 설명)
II. 정규표현식 소개 (이 포스트에서 설명)
III. AWK (이 포스트에서 설명)
IV. AWK Examples(이 포스트에서 설명)
V. SED (다음 포스트에서 설명)
VI. SED Examples(다음 포스트에서 설명)


I. AWK와 SED 배경

AWK 역사적 배경

1977년 Bell Laboratories의 Alfred Aho, Peter Weinberger 그리고 Brian Kernighan이 처음 개발했다. 이 셋의 이름을 따 AWK라 부르고 auk[ɔ́ːk]로 발음한다. 옆에 있는 사진은 바다쇠오리라는 새인데 영어로 auk라 부른다. AWK와 발음이 같기 때문에 AWK 책에 표지모델로 쓰기이기도 했다.
1979년 Version 7 Unix에 처음 배포되었다. V7 Unix는 역사적으로 의미가 있는 유닉스다. 유닉스는 벨연구소에서 PDP-7에 MULTICS를 이식하면서 개발이 시작됐고 1970년 PDP-11에 포팅되면서 UNIX의 첫번째 판이 나왔다. 1973년 Versioin 4 Unix는 C언어로 재작성됐고 1974년 대학에 널리 알려지게 되면서 대학과 벨연구소가 함께 개발하기 시작했다. 그리고 1979년에 V7이 나왔고 여기에 최초로 C 컴파일러와 본셸이 들어갔다. 물론 AWK와 SED도 이 버전에 최초로 포함됐고 make도 이때 포함됐다. 역사적으로 의미가 있다는 이유는, V7이 research unix로서 널리 알려진 유닉스 중 마지막 버전이기 때문이다. 즉, 1980년대  들어서 유닉스가 상업적으로 사용되기 시작했는데, 그 전에 나온 마지막 유산이라는 뜻이다. 물론 V8, V9, V10까지 나오긴 했었지만 V7만큼 알려지진 않았다. 게다가 많은 유닉스 변종들은 V7을 기반으로 했고 그 중 BSD와 SystemV는 또 그 후에 모든 상업적 유닉스의 기반이 됐기 때문에 역사적으로 V7이 중요한 의미를 가진다고 말할 수 있다.


SED 역사적 배경

SED는 Stream EDitor에서 따온 이름이다. 읽을 때는 세드라고 발음한다.  1973년 벨연구소의 Lee E. McMahon이 개발했다. 추측컨대 그 당시의 벨연구소는 지금의 구글보다 더 높은 위상을 가졌을 것 같다. 벨연구소는 전화장비, 물리분야, 네트워크, 소프트웨어 등 첨단 기술의 리더 역할을 했다. 그 연구소에서 완료한 연구 업적으로 7번의 노벨상이 수여됐다고 한다. 하지만 1996년 벨연구소의 전화장비와 물리연구분야가 Lucent Technologies로 독립했고 소수만 남아서 AT&T Bell Laboratories를 이어갔다. 그후 AT&T Laboratories로 존재하다가 2005년에 AT&T Corp.가 통째로 SBC Communications에 인수됐고 SBC Communications는 자신의 이름을 AT&T Inc.로 바꿨다. 그리고 AT&T Corp.의 일부였던 AT&T Laboratories는 SBC Communications의 R&D  부서에 흡수됐고 그 부서 역시 AT&T Labs. Inc 로 자신의 이름을 바꿨다. 예전에 정점을 달리던 AT&T는 사실상 SBC Communications에 흡수되어 사라졌다. 단지 AT&T 이름이 상징적이기 때문에 SBC Communications가 그 이름을 계속 사용하는 것이다.
SED는 AWK와 마찬가지로 1979년 Version 7 Unix에 처음 배포됐다. 그러나 80년대 중반에 perl 등장했고 널리 알려지기 시작하면서 AWK와 SED의 사용 빈도는 급격히 줄었다. 왜냐하면 조금만 길어져도 스크립트가 너무 복잡해지기 때문이다. 그렇기 때문에 복잡한 프로그래밍으로는 거의 사용되지 않고 관용적인 one-liner로써 명맥을 이어가고 있는 실정이다. sed는 ed로 부터 비롯됐고 perl에 영향을 주었다.
*one-liner 라는 단어는 명령행에 한줄로 쓰여져 동작하는 프로그램을 뜻한다.



II. 정규표현식

AWK와 SED는 정규표현식이 적용되지 않아도 작동하지만, 정규표현식을 사용하면 AWK와 SED로 할 수 있는 일이 훨씬 많아진다.

정규표현식이란 텍스트 안에 있는 복잡한 패턴을 표현하는 방법이다. 정규표현식은 정규식으로 줄여서 쓸 수 있고 regular expression은 regex 또는 regexp로 줄여서 쓸 수 있다. 발음하기는 regex가 편하고 레긱스 내지는 레직스라고 읽을 수 있다. 대체 regexp는 어떻게 발음하는지 모르겠다. 아시는 분은 제보 부탁드린다 ;^)

정규표현식은 automata theory와 formal language theory 연구에서 시작됐다. 그리고 최초로 정규표현식을 적용시킨 유틸리티는 Ken Thompson의 QED이다. 또한 나중에 Ken Thompson은 ed에도 정규표현식 기능을 넣었고 이로 인해 정규표현식이 널리 알려지게 됐다. 현재 정규식을 지원하는 유틸리티 중에 가장 유명한 것은 grep일 것이다. grep은 ed에 직접적으로 영향을 받았다. ed 명령어 g/re/p에서 그 이름을 따올 정도였으니까 말이다. 현재 다양한 에디터, 프로그래밍 언어 (특히 스크립팅 언어) 그리고 많은 텍스트 프로세싱 유틸리티들에서 정규표현식이 지원된다.

이 문서에서는 널리 쓰이는 AWK와 SED의 관용구들을 이해할만한 선에서 정규표현식의 일부를 소개한다. 그 선이라는 것은 내 경험을 바탕으로 정한 것이므로 절대 '정규표현식은 이게 전부다'라고 믿지는 말라 :P

누구나 워드 프로세서의 '찾기' 기능을 써본 적 있을 것이다. 정규표현식이 없는 '찾기'는 사용자가 입력한 스트링에 문자 그대로 정확히 매칭되는 단어 또는 문장만 찾을 수 있다. 그런데 정규표현식을 사용하면 '찾기' 기능에 "전체 텍스트 중에서 이러저렇게 생긴 부분을 찾아줘"라고 말할 수 있다. 다시 말하자면, "이 패턴을 가진 부분을 찾아라"라고 명령할 수 있다는 얘기다.

Characters and Character class

abc : abc 캐릭터 그대로
\t   : tab 캐릭터
\n  : newline 캐릭터
[abc] : a or b or c 대괄호는 정규식에서 특수한 의미를 가진다. 대괄호는 캐릭터 클래스를 형성한다. 문자 그대로의 대괄호를 매칭시키고 싶으면 백슬래시를 앞에 두어야 한다. \[ \]
[a-z] : 소문자 a~z 캐릭터 클래스는 범위로 지정할 수도 있다.
[A-Z] : 대문자 A~Z
[0-9] :  숫자 0~9
[a-zA-Z0-9] 다중 범위를 지정할 수도 있다.
[^abc] : abc 제외(반드시 ^이 맨 처음에 나와야함) 캐릭터 클래스에 맨 첫 글자가 ^면 ^이 특별한 의미를 가진다. 캐릭터클래스 안에 있는 캐릭터를 제외한 아무 캐릭터를 뜻한다. 만약 캐릭터 클래스의 맨처음이 아니라 중간에 ^이 들어가면 문자그대로의 ^을 뜻한다.
 .      : 아무 character. 점하나가 아무 캐릭터 하나를 뜻한다. 빈칸도 되고 알파벳, 숫자, 특수기호 등도 가리킨다.


경계(boundary)


^  : 행의 맨 처음
$  : 행의 맨 끝, 그렇기 때문에 ^$은 아무캐릭터가 없는 행 즉, 빈행을 의미한다
\w : 단어. 영숫자를 의미함.
\W:  단어가 아닌 캐릭터. 즉, ~`!@#$%^&*()-+=|\{}[];':"?/<>,. 그리고 공백문자를 뜻한다.
\b: 단어 경계(이질성)
\B: 비 단어 경계(동질성)


이해를 돕기 위해 \b, \B, \w, \W의 예를 들어보겠다.
abcdef:!~ghi-jkl에 대해
 패턴 매칭
(\B\w)* abcdef:!~ghi-jkl
 (\b\w)* abcdef:!~ghi-jkl
 (\b\W)* abcdef:!~ghi-jkl
 (\B.\B)* abcdef:!~ghi-jkl
 (\b.\b)* abcdef:!~ghi-jkl

즉 \B는 자기와 같은 그룹(단어냐 비단어냐)에 속한 녀석에 둘러쳐졌는지 보는 것이고 \b는 자기와 다른 그룹에 속한 녀석에 둘러쳐졌는지 본다.


횟수(quantities)


* : 0번 이상 나옴, 예) a*b  : bbb 매칭
+ : 1번 이상 나옴, 예) a+b  : bbb 매칭 안됨
?  : 0,1번
{n,m} n~m번
{,m} ~m번
{n,} n번이상
{x} x번


캡처링 그룹과 백레퍼런스(capturing groups and back references)

()  패턴을 그룹으로 묶음, 그룹화의 가장 큰 목적은 나중에 특정 그룹을 가리키기 위해서이다.
\n n번째 그룹 가리키는 백레퍼런스
백레퍼런스 지정 순서: 왼쪽 괄호가 등장한 순서대로 해석한다.
((A)(B(C)))  
               \1 : ((A)(B(C)))
   \2: (A) 
   \3: (B(C))
               \4: (C)


백레퍼런스의 키포인트: 백레퍼런스로 가리키는 것은 매칭된 결과 값임을 주의! 패턴을 가리키는 것이 아님!

여기저기서 갖고 온 것들 :P

\  : 인용부호; 특수 캐릭터의 해석을 막음
       예) \^ 행의 처음이라는 의미 상실 
            \\ 알파벳에 특수한 의미를 부여하는 기능(이스케이프 시퀀스) 상실
            \. 아무 캐릭터나 가리킬 수 있는 기능 상실
X|Y : X or Y
\s : 공백문자
\S : 공백문자를 제외한 캐릭터
[\]: \\ 한 것과 의미 동일
[.^]: \. 과 \^ 한 것과 의미 동일



III. AWK

syntax

1. pattern{ action statements }
2. function name(parm list) { statements }

2번은 함수를 정의하는 문법이다. C와는 조금 다른 점은 parm list에 매개변수 뿐만아니라 로컬변수도 써줘야 하는 점이다. 그 점 외에는 특별한 것이 없다.

awk의 프로세싱은 입력 스트림 => awk processing => 출력 스트림이다. 입력 스트림은 파일 또는 표준 입력을 지정할 수 있다. 출력 스트림 역시 파일 또는 표준출력임은 두말하면 잔소리다. 그중 awk processing 부분이 우리가 주목해야할 부분인데 1번에 나온 문법대로 프로그래밍을 해야 한다.
즉 입력스트림을 받아서 pattern에 적용해 보고 패턴에 일치하면 action statements 를 실행하는 것이다. 또한 다수의 pattern{ action }을 체인으로 사용할 수 있다. 1번을 조금 더 C와 비슷한 모양으로 고치면 이렇게 쓸 수도 있다. pattern{ action } 에서 pattern 부분을 생략하고 action의 if 문 안에 패턴을 검사하는 statement를 넣었다.
{
   if (pattern) {
         action statements
   }
}


보다시피 pattern{ action }의 pattern 은 생략가능 하다. 이 경우 모든 입력스트림에 대해 {action}을 수행하게 된다.

그리고 pattern{ action } 에서 { action }도 역시 생략 가능하다! 이 경우 pattern과 일치하는 입력 스트림 부분을 print하는 action이 자동으로 실행한다.


AWK를 배우는데 문법 구조 외에 알아야 할 게 또 있다. 바로 미리 정의된 변수들(pre-defined variables)이다. 이 변수들은 각각 특별한 값을 가지게 되는데 상황에 따라 매번 변하는 변수도 있고 사용자가 변경하지 않는한 계속 그대로인 변수도 있다.

또한 AWK는 일반변수와 배열도 지원한다.

그리고 다양한 표준 함수들도 가지고 있다.

이제 어째서 AWK를 프로그래밍 언어라고 하는지 감이 오지 않는가? 이제 위에 나열한 AWK의 기능들을 설명하겠다. 이 문서는 레퍼런스라기보다는 초보자용 가이드라인이므로 awk의 모든 기능을 설명하는 대신 자주 사용되는 기능들만 설명한다.


pre-defined variables

미리 정의된 변수들이 있다. built-in variables 라고 부르기도 한다. 이 변수들을 이해하기 위한 몇가지 개념을 먼저 소개하겠다. record나 field는 awk의 입력으로 들어온 전체 텍스트 중 일부다. 전체 텍스트가 awk를 거치는 모습은 간단히 이렇게 그릴 수 있을 것이다.
Input ==> awk processing ==> output
input 은 표준입력이 될 수도 있고 평범한 파일일 수도 있는데 awk는 작업을 처리하기 위해서 input을 통째로 작업대 위에 올려놓지 않고 부분부분 잘라서 올려놓는데 이 때 작업대 위로 올려놓은 게 레코드다. 그리고 그 레코드는 또 필드로 이루어져 있다.


이제 '변수이름: 의미' 형식으로 미리정의된 변수들의 의미를 중요한 것만 알아보겠다.

RS: record separator (디폴트는 개행문자)
FS: field separator (디폴트는 공백문자)
NF: the number of fields (FS로 나뉜 한 레코드 안의 필드 개수)
ORS: output record separator(디폴트는 개행문자)
NR: total number of record so far(현재 라인 번호)
ARGC, ARGV: 매개변수의 개수와 매개변수를 가리키는 변수
FNR: number of record in the current input file
OFS: ouput field separator(디폴트는 공백문자)
FILENAME: name of input file
SUBSEP: separate multiple subscripts in array elements(,; \034; \0x1C)
IGNORECASE: 값이 0이 아니면 패턴 매칭에 대소문자 구별 안 함


RS는 awk가 전체 텍스트 중 작업대 위로 레코드를 올릴 때 어떤 단위로 올릴지 정하는 변수라 할 수 있겠다. 디폴트 값은 newline 캐릭터이므로 이 때 awk는 grep이나 sed처럼 한 줄 씩 끊어서 작업한다고 말할 수 있다.
FS는 레코드 내의 필드들의 구분자이다. 기본 값은 공백이므로 어떤 레코드의 내용이 abc def ghi jkl 이면 1번 필드($1)는 abc,2번($2)은 def 이런 식이다. 그리고 $0은 abc def ghi jkl 이다. 즉 현재 레코드의 전체 부분을 가리킨다.
awk의 매개변수에 파일을 여러개 지정했다면 FNR과 NR의 차이점도 알아야 한다. FNR은 지금 awk가 작업하고 있는 파일 내에서 몇번째 레코드인지 가리키고 NR은 파일 구분 없이 맨처음부터 지금까지 총 몇번째 레코드인지 가리킨다.
SUBSEP은 배열 사용시 필요한 내용인데, 배열을 설명할 때 부가 설명드리겠다.

시험삼아 위에 설명한 내장 변수들을 사용한 몇가지 간단한 관용구처럼 사용되는 one liner들을 따져보자.

1. awk 'NR%2==0{ print $0 }'
2. awk 'NR%2'
3. awk '0'
4. awk '”0”'
5. awk 'NR>5&&NR<10'
6. awk '$0 = NR" "$0'

1번은 짝수 줄NR%2==0이면 출력하라{ print $0 }는 뜻이다. 2번은 홀수 줄이면 출력하라는 뜻이다. 왜냐하면 NR이 홀수 줄이면 NR%2 가 0이 아니므로 디폴트 액션인 { print $0 }이 출력되기 때문이다. 여기서 NR%2의 값은 0또는 1인데 0은 false를 뜻하고 0이 아닌 숫자는 true를 뜻한다. 3번은 아무 줄도 출력하지 않는다. 왜냐하면 항상 0, false이기 때문이다. 4번은 항상 출력한다. "0"은 문자열이기 때문에 항상 참이다. 5번은 6,7,8,9 줄을 출력한다. 6번은 줄앞에 줄번호를 붙인다. $0은 현재 레코드인데 $0 = NR" "$0 은 $0에 NR" "$0을 대입하라는 의미이다. 중간에 " " 은 단지 줄번호(NR)과 레코드($0) 사이에 공간을 두기 위해 붙인 문자열에 지나지 않는다.

변수와 배열

변수는 숫자거나 스트링일 수 있다. awk의 변수와 배열은 따로 초기화하거나 타입을 지정할 필요가 없으며 필요시 자동으로 형변환이 된다. 즉 사칙연산이 필요할 때는 숫자였다가 문자열 이어붙이기를 할 때는 스트링이 되기도 한다.

초기화가 필요 없으므로 곧바로 a++; 이렇게 쓸 수도 있다. 이때 a의 값은 1이 된다. 왜냐하면 초기화하지 않은 변수의 값은 숫자의 경우 0이기 때문이다. 그리고 변수에 octal 과 hexadecimal 값을 넣을 수 있다.  a=0nn;, b=0xnn; 이렇게 사용하면 된다.

변수에 스트링을 대입하는 방법은 a="string" 이런 식이다. 또한 스트링 안에 이스케이프 시퀀스도 사용할 수 있다. 몇가지 이스케이프 시퀀스의 예는 다음과 같다.
\\: 백슬래시 캐릭터 그대로. 백슬래시는 이스케이프 시퀀스를 만들 때 사용되므로 문자 그대로의 백슬래시를 써야할 때는 백슬래시를 두개붙여쓴다.
\a: ASCII의 BEL 캐릭터
\b: 백스페이스 캐릭터
\n: 개행문자
\r: 캐리지 리턴
\t: 수평 탭
\v: 수직 탭
\ddd: octal value로 표현되는 캐릭터. 0-7까지의 숫자만 이용해서 캐릭터를 표현하며 범위 밖의 숫자 또는 문자는 이스케이프 시퀀스에 해당하지 않는다. 즉 그 앞 부분까지만 octal value로 표현되는 이스케이프 시퀀스다. 예를들어 "\438"은 #8이다.
\xnnn: hexadecimal value로 표현되는 캐릭터. 역시 \x 뒤를 따르는 모든 16진수 숫자들을 이스케이프시퀀스로 받아들이고 범위를 벗어나면 그냥 문자그대로로 인식한다. 예를들어 "\x23G"는 #G이다.


배열도 변수와 마찬가지로 초기화가 필요하지 않다. 다짜고짜 a[0]++; 이런 식으로 쓸 수 있다. 그리고 특이하면서 유용하게 사용되는 특징은 배열의 인덱스에 스트링을 넣을 수 있다는 점이다. 그리고 숫자로는 음수나 소수를 넣을 수 있다. 예를 들어
a["Foundations of AWK"]=1; 이렇게 쓰거나 a[-12.07]++; 이렇게 쓸 수도 있다. 또한 awk의 배열은 다차원 배열을 흉내낼 수 있는데 다음과 같이 쓸 수 있다. 
a["Foundations of AWK","Junyeong"]="Jeong";
a["Foundations of AWK","Alfred"]="Aho";
a[0,1,0]="Kernighan";
i=0; j=1; k=1;
a[i,j,k]="Weinberger";

즉 배열의 섭스크립트를 여러 문자열이나 숫자의 조합 또는 변수의 조합으로 사용할 수 있으며 조합시에 , 를 사용하는데 이것은 아까 pre-defined 변수에서 SUBSEP 변수의 값인 캐릭터이다. 이 캐릭터가 눈에 잘 띄지 않는다면 SUBSEP변수를 바꿔서 다른 캐릭터로 변경해도 되고 캐릭터를 octal 이나 hexadecimal 값으로 기입해도 상관없다. 즉 위의 예를
a["Foundations of AWK\034Junyeong"]="Jeong";
a["Foundations of AWK\034Alfred"]="Aho";
이렇게 쓸 수 있다는 말이다. 물론 a["Foundations of AWK","Junyeong"]="Jeong"; 으로 값을 할당하고 a["Foundations of AWK\034Junyeong"] 으로 값을 가져오는 것도 당연 가능하다. 단지 "," 캐릭터를 스트링의 이스케이프 시퀀스로 표현했을 뿐이기 때문이다.

그리고 배열의 특정 섭스크립트를 검색하는 연산자로서 in 이 있다. 사용법은 subscript in array이다. 만약 위의 예를 적용하면
if ("Foundations of AWK\034Junyeong" in a) print a["Foundations of AWK\034Junyeong");
이다. 혹은 if (("Foundations of AWK","Junyeong") in a) print a["Foundations of AWK","Junyeong"]; 도 똑같다.



패턴

AWK의 syntax, awk 'pattern{ action statements }' 중에서 pattern 부분을 작성하는 방법은 다음과 같다.

BEGIN{ }: 모든 인풋보다 먼저 실행되는 statements를 지정, 즉 awk의 작업대에 첫 레코드가 올라가기 전에 실행되는 statement들의 블록을 지정하는 셈이다. 초기화 작업을 하는 곳이라고 생각하면 된다. BEGIN 패턴은 한 awk 명령에 여러번 나올 수 있는데 모든 BEGIN블록은 한데 모아진다.
END{}: 더 이상 인풋이 없을 때 실행되는 statements지정. 역시 END블록은 여러번 나올 수 있고 하나의 END블록으로 모아진다.
/정규식/: / / 로 묶어서 정규식을 사용할 수 있다.
패턴1 && 패턴2: AND 논리 연산, 물론 패턴이라는 말은 /정규식/도 내포한다.
패턴1 || 패턴2: OR 논리 연산
!패턴: NOT 논리 연산,
패턴1, 패턴2: range pattern인데 패턴1인 레코드로부터 패턴2인 레코드까지인 범위를 지정한다.



연산자들

기본적으로 C에서 사용할 수 있는 연산자들(포인터나 구조체 관련한 연산자 제외)을 사용가능하다. 거기에 덧붙여 AWK에서 사용되는 특별한 연산자들이 있으니 그것만 여기 소개하겠다.
$: field reference, 레코드에서 FS로 구분되는 필드를 가리킨다. 특별히 $0은 모든 필드들을 뜻한다.
space: 공백 연산자는 스트링과 스트링을 붙이는데 사용한다.
|, |&: getline, print, printf에 사용되는 piped I/O
~, !~: 정규표현식 매치, 비매치. 정규식을 연산자의 오른쪽에 써야만 한다.
in: 배열에서 특정 섭스크립트 검색

제어문

C에서 사용하는 제어문과 비슷하다. AWK는 C를 많이 따랐기 때문에 비슷한 것은 당연하다. 다만 배열에 관련해서 delete문이 있고 switch문은 없는데, switch 문은 awk의 옵션으로 --enable-switch로써 사용가능하다.
if (condition) statement [ else statement ]
while (condition) statement
do statement while (condition)
for (expr1; expr2; expr3) statement
for (var in array) statement
break
continue
delete array[index]
delete array
exit [ expression ]
{statements }


I/O 문

I/O statements는 여러 종류가 있지만 그중 자주 사용되는 getline과 print, printf만 알아보겠다. 다른 종류(close, system, fflush, next, nextfile) 대해서는 맨페이지를 참고하시라 ;^)

getline: 다음 레코드를 $0로 설정함
getline < "file": 다음 레코드를 "파일"에서 가져온다
getline var: 다음 레코드를 변수 var에 넣는다
getline var < "file": 다음 레코드를 "파일"에서 가져와서 변수 var에 넣음
"command" | getline [var]: "command"를 실행하여 표준출력을 파이프로 넘기고 넘어온 입력을 getline이 $0 [또는 변수var]으로 설정한다
"command" |& getline [var]: "command"를 co-process로 실행시켜 표준출력을 파이프로 넘이고 getline은 넘어온 입력을 $0 [또는 변수var]로 설정한다
print: 현재 레코드를 출력한다. 출력된 레코드는 ORS가 맨 끝에 붙음
print expr-list: 표현식을 출력한다. 각 표현식은 OFS로 구분되어 출력된다. 예를 들어 print $1, $2;
print expr-list > "file": 표현식을 "file"로 출력한다
print expr-list >> "file": 표현식을 "file" 끝에 덧붙인다
print expr-list | "command": 표준출력을 파이프에 쓰고 "command"에서 그 파이프를 표준입력으로 받는다
print expr-list |& "command": print 표준출력을 파이프에 쓰고 "command"는 co-process로 실행돼 파이프에서 표준입력을 읽는다
printf format, expr-list: C의 printf처럼 포맷을 지정해서 표현식을 출력한다(포맷은 C와 유사하며 자세한 내용은 awk맨페이지를 참고하시라)
printf format, expr-list > "file": 포맷을 지정해서 표현식을 파일로 출력한다.

위의 설명들은 쭉 읽어보면 아마 하나 빼고 바로바로 이해가 될 내용일 것이다. 그 하나는 바로 co-process 를 실행시킨다는 |& 연산자를 사용한 부분일 것이다.
"command" | getline 이나 print | "command" 중 전자는 각각 "command"의 표준출력을 getline의 표준입력으로 보낸 것이고, 후자는 print의 표준출력을 "command"의 표준입력으로 보낸 것이다. 둘 다 일방통행이라는 공통점이 있다. 그런데 |& 연산자를 사용할 시에는 "command"를 co-process(awk와 어깨를 나란히 하고 같이 뛰는 프로세스)로 실행시키게 된다. 그러므로 양방향 통신이 가능한데, 무슨 뜻이냐하면 print |& "command1"; "command1" |& getline 처럼 사용해서 print로써 명령으로 입력을 보내고 getline으로 결과를 받아본다는 뜻이다. 당연히 양쪽에 기입된 "command1"은 서로 같아야 출력을 올바로 볼 수 있다. 실제 예를 보면 확실히 이해가 될 것이다.
to_upper 배시 셸 스크립트
#!/bin/bash
#set -x
while read arg
do
    echo "$arg" | tr '[a-z]' '[A-Z]'
done

g6라는 awk 스크립트
{
  print $0 |& "./to_upper"
  "./to_upper" |& getline hold
  print hold
}

이제 이 awk 스크립트를 명령행에서 이렇게 실행시킨다
$ awk -f g6 < SOMEFILE

결과는 SOMEFILE 안에 있는 모든 영소문자들이 영대문자로 치환되어 출력된다. 만약 g6의 |&대신 |을 사용한다면 의도한대로 실행되지 않을 것이다. 비록 첫번째 statement는 ./to_upper로 print의 출력을 입력시킬 순 있지만 두번째 statement의 ./to_upper 프로세스는 첫번째 statement에서 돌아간 ./to_upper의 프로세스랑 다른 것이므로 원하는 결과는 얻을 수 없다!

I/O문에서 사용하는 특별한 파일들

리다이렉션을 이용해 파일로 print, printf 의 결과를 출력하거나 getline으로 파일에서 입력을 받을 수 있는데, 몇몇 파일이름들은 이미 awk가 특별한 의미를 부여해 놓았으므로 파일시스템 상의 파일을 의미하진 않는다.

/dev/stdin: 표준입력
/dev/stdout: 표준출력
/dev/stderr: 표준에러
/dev/fd/n: n번 파일디스크립터
/inet/tcp/lport/rhost/rport: TCP/IP 커넥션. 로컬의 포트는 lport, 원격호스트는 rhost, 원격포트는 rport. lport를 0으로 지정하면 운영체제가 알아서 선택한다.
/inet/udp/lport/rhost/rport: UDP/IP 커넥션. TCP/IP 와 사용법 같다.

그리고 현재 실행 중인 awk 프로세스에 대한 정보를 얻기위해
/dev/pid, /dev/ppid, /dev/pgrid, /dev/user 를 사용할 수 있다. gawk에서는 이 파일들 대신 미리정의된 변수인 PROCINFO 배열을 사용한다. PROCINFO에서 사용되는 섭스크립트는 다음과 같다. "FS", "egid", "euid", "gid", "group1", "group2", "pgrpid", "pid", "ppid", "uid", "version"


AWK가 제공하는 표준 함수들

표준함수에 대한 내용은 이문서에 설명하지 않겠다. 함수에 대한 설명이 맨페이지에 일목요연하게 나와있기 때문이다. 다만, 표준함수들에 대한 분류만 보기 좋게 써보겠다.
Numeric functions
String functions
Time functions
Bit Manipulation functions
Internationalization functions(since gawk 3.1)

뭐니뭐니해도 스트링 함수들이 가장 자주 사용되므로 거기에 있는 유용한 함수들은 잘 알아두는 게 좋다.


사용자 정의 함수

맨처음 syntax 섹션에서 function name(parm list) { statements }라고 적어놓은 것을 기억할 것이다. 이게 함수를 정의하는 방식이다. 특이한 점은 parm list 에 로컬 변수도 적어줘야 하는 점이다. 그리고 함수이름 name과 왼쪽 괄호 ( 는 떨어져서 안 된다. 예를 들어
function test(p, q,          i, j) {
      statements
}
p,q 는 함수를 호출 시 넘겨야하는 파라미터고 i,j 는 statements에서 사용되는 로컬 변수이다. 관습적으로 파라미터와 로컬변수 사이는 널찍하게 스페이스를 둔다.


awk 옵션들

커맨드라인에서 awk를 실행시킬 때 유용하게 쓸 수 있는 옵션 몇가지를 추려보았다.
-F fs: FS의 값을 지정한다. BEGIN{ FS="fs" } 이렇게 한 것과 같다.
-v var=val: 변수 var를 val로 지정한다. BEGIN{var=val} 한 것과 같다
-f file: awk 스크립트를 지정한다
--dump-variables[=file]: global 변수들의 이름과 값을 출력한다. file을 지정하지 않으면 현재 디렉터리의 awkvars.out 파일로 출력한다. 디버깅용으로 사용할 수 있다.
--re-interval: 정규표현식 중 인터벌을 사용할 수 있게 한다. {n,m}



IV. AWK Examples

앞에서 이론 공부를 했으니 이제 몇가지 예제를 보면서 익히는 게 좋을 것 같다. 우아한 것들로 골라봤다.

1. awk '$7 ~ /^[a-f]/'
7번 필드가 정규식 /^[a-f]/에 매칭된다면 출력한다.

2. awk '$7 !~ /^[^a-f]/{ print > “/proc/self/fd/2” }'
바로 앞의 예와 같은 패턴 매칭이지만 출력을 표준에러로 한다. "/dev/stderr" 를 대신 쓸 수 있다.

3. awk 'NF'
NF가 0(false)이 아니면 출력한다. 즉 빈행이 아니면 출력한다. 여기서 action statements는 생략됐으므로 디폴트인 { print $0 }가 실행됨은 이제 다들 아실거라 생각한다.

4. awk 'NF{ $0=cnt++" "$0}1'
NF가 0이 아니면 줄 앞에 cnt를 표시한 뒤 출력한다. 1이라는 숫자에는 의미가 없다. 단지 패턴에 0이 아닌 다른 숫자나 스트링이 오면 항상 true 이기 때문에 디폴트 액션이 실행된다.

5. awk '{ sub(/^[ \t]*/,""); print }'
표준 스트링 함수인 sub(pattern,replacement) 를 사용했다. 모든 패턴에 대해서 sub(/^[ \t]*/,"") 를 적용하며 이 함수는 레코드 자체를 수정하므로 리턴값을 받을 필요는 없다. 함수 의미를 풀면 정규식 ^[ \t]* 를 지우라는 뜻이다. 즉, leading 공백문자들을 삭제한다.

6. awk '{ gsub(/^[ \t]*|[ \t]*$/,"") }1'
이것은 앞선 예와 비슷한 기능이다. gsub() 함수는 sub의 global버전이라 할 수 있겠다. sub은 최초 매치만 substitution을 행함에 반해 gsub은 모든 매치들에 대해 substitution을 수행한다. 위 one-liner의 뜻은 모든 leading whitespace 캐릭터들 (^[ \t]*) 또는 (|) 모든 trailing whitespace 캐릭터들 ([ \t]*$)을 제거하라는 뜻이다. 그리고 맨 마지막에 1을 붙여서 디폴트 액션을 수행하게끔 하였다.

7. awk '!a[$0]++'
이것은 배열의 섭스크립트에 스트링도 넣을 수 있다는 점과 awk에서 변수나 배열은 초기화가 필요하지 않다는 점을 십분활용한 예다.
만약 현재 레코드가 처음 나온 레코드라면(현재 라인이 앞선 라인들과 중복되지 않은 라인이면) a[$0]의 값은 0이다. 그러므로 !a[$0]은 0이 아니다. true다. 패턴이 true이므로 디폴트 액션문이 실행되는 조건을 만족시킨다. 그러고 나서 a[$0]을 1 증가시켜서 (a[$0]++) 값이 1이 된다. 만약 나중에 똑같은 레코드가 들어왔다면, !a[$0]은 false가 돼서 출력은 되지 않을 것이다. 그래도 a[$0]++은 실행되므로 값이 증가된다. 결론적으로 이 one-liner의 역할은 중복된 라인을 제거하면서 똑같은 라인의 개수를 파악하는 것이다.

8. awk 'BEGIN{FS=""}{ for (i=NF;i>=1;i--) printf "%s",$i; print ""}'
우선 인풋이 들어오기 전에 BEGIN{} 블록을 실행한다. FS를 널스트링으로 바꿨다. FS 의 값 설정은 awk -F"" 로써 편리하게 할 수도 있다. FS가 널스트링이면 한개의 필드는 한개의 캐릭터에 대응된다. for 문에서 사용한 NF는 필드의 개수를 뜻하므로 i=NF는 마지막 필드를 가리키는 셈이다. for문을 돌면서 현재 i가 가리키는 필드를 printf문으로 출력한다. 즉 맨마지막 캐릭터부터 맨앞 캐릭터까지 역순으로 출력한다. 마지막 print "" 는 단지, 마지막에 ORS를 붙여주기 위함이다.

9. cat /usr/man/man1/awk.1 |grep '\(^\.SH\|^\.SS\)'|awk '/\.SS/{ $0 = "    "$0}{sub(".SH",""); sub(".SS", "")}1'
awk 맨페이지를 cat으로 읽은 뒤 타이틀을 뜻하는 .SH와 .SS 라인만 추려내 그 라인을 보기 좋도록 .SH와 .SS를 떼어내는 one-liner이다. 즉 맨페이지의 목차를 보여준다. 만약 맨페이지가 gzip 압축됐다면 cat 명령어를 gzip -cd 로 대체하면 된다.

10. awk 'NR==40001,NR==40100{ array[$3]++};END{ size=asorti(array,dest); for (i=1; i <= size; i++) {print dest[i], array[dest[i]]}}' /var/log/messages
messages 파일 중 40001번째 줄부터 40100번째 줄까지 읽고 세번째 필드의 출현 횟수를 기록한다. messages의 세번째 필드는 시각이다. 그러고 나서 모든 인풋이 소진되면 END블록이 실행된다. asorti 는 표준 스트링함수인데 array배열을 받아서 배열의 값대로 정렬한 뒤 결과를 dest 배열의 값에 넣고 인덱스는 1번부터 시작해 증가시킨다. 즉 dest배열은 시간순으로 정렬된 셈이다. 그리고 마지막 for문에 print dest[i], array[dest[i]] 로써 "시간  출현횟수" 형식으로 출력한다.

11.  awk 'END{ print NR}'
모든 인풋이 소진되고 END블록이 실행된다. NR의 값은 마지막 줄번호를 가리키므로 총 라인 수를 출력하는 셈이다.

12. awk 'BEGIN{ mysql="mysql -u rhdxmr --password=somepassword mydb" } { string1="\047Jaco Pastorius\047"; string2="\047Cha Cha\047"; print "insert into test values("string1","string2");"|mysql}'

이 예에서는 print I/O statement의 표준출력을 | 연산자로써 외부 프로그램의 표준입력에 주었다는 것이 주목할 점이다. 명령행에서 작은 따옴표를 넣으면 의도와 다르게 배시에서 파싱돼버리므로 octal value인 \047로 작은 따옴표를 표현했다. 그래서 MySQL에 입력된 쿼리문은 insert into test values('Jaco Pastorius','Cha Cha');다. 이 예에서 처럼 쿼리문의 일부를 변수로 대체시켜 상황에 따라서 다른 쿼리문을 생성할 수 있다.

13. awk 'length < 86'
length는 변수처럼 보이지만 원래는 표준 함수 length()이다. awk에서 유일하게 변수형태와 함수형태 모두 사용가능한 녀석이다. 이것은 어디까지 historical feature이므로 깊게 생각할 필요는 없다. length 는 length($0)와 같은 의미인데 이 one-liner는 한 레코드의 전체 길이가 86이하인 짧은 줄만 출력하라는 뜻이 된다.

14. awk '{ print $NF }'
NF는 현재 레코드의 총 필드의 개수를 의미하는데 이는 곧 마지막 필드가 몇번째 필드인지 가리킨다. 그러므로 print $NF는 마지막 필드를 출력하라는 의미이다.

15. awk '{  for(i=1; i<=NF; i++) A = A" "$i; print A; A = "" }'
i의 초기값으로 지정된 필드부터 마지막 필드까지 출력한다. for문의 i값에 처음 출력을 원하는 필드번호를 적으면 그 필드부터 마지막 필드까지 출력한다.

여기까지 먼길을 왔는데 AWK에 대한 설명은 이쯤에서 마치도록 하겠다. 조금 쉬었다 바로 SED가 무언지 보러 갈테니 아직 긴장을 풀지 마시길. 낄낄


출처 : http://rhdxmr.tistory.com/57
반응형

'OS > Linux' 카테고리의 다른 글

CENTOS 7에 XRDP 설치하기  (0) 2017.08.26
리눅스 백업 및 복구  (0) 2013.01.25
삼성 컴퓨터 유분투 설치기.  (0) 2012.02.06
rkhunter (리눅스 침입 탐지 사용하기)  (1) 2010.10.14
ps auxc 와 ps aux 결과 비교하기  (0) 2010.01.21

+ Recent posts