공룡호가 사는 세상 이야기

맘에드는 아티클이다. 명령행 기교와 연산자를 익히면 유닉스가 정말 가깝게 느껴진다.
일단 시스템에 문제가 생기거나 점검을 수행할 때, 프로세스를 확인하는 것은 흔한 일이다.
시스템의 퍼포먼스가 떨어졌다던가. I/O가 느려졌다던가.
이유를 찾기 위해선 어떤 프로세스가 CPU나 DISK를 얼마나 점유하고 있는지 찾고,
평소에 그렇지 않은데, 지금 그러한 이유가 무엇인지 찾아나가는 순서로 진행된다.
프로세스를 확인 해 보자.

# ps -ef
     UID     PID    PPID   C    STIME    TTY  TIME CMD
    root       1       0   0   Jul 27      -  0:05 /etc/init
    root   53442  151674   0   Jul 27      -  0:00 /usr/sbin/syslogd
    root   57426       1   0   Jul 27      -  0:00 /usr/lib/errdemon
    root   61510       1   0   Jul 27      - 23:55 /usr/sbin/syncd 60
    root   65634       1   0   Jul 27      -  0:00 /usr/ccs/bin/shlap64
    root   86102       1   0   Jul 27      -  0:00 /usr/lib/methods/ssa_daemon -l ssa0
                                                .
                                            (중략)
                                                .
    root  315646  151674   0   Jul 27      -  0:00 /usr/sbin/lpd
    root  319664       1   0   Jul 27      -  0:00 /usr/atria/etc/albd_server
    root  340144  168018   0 12:34:56      -  0:00 rpc.ttdbserver 100083 1
    root  376846  168018   0   Jul 30      -  0:00 rlogind
 cormany  409708  569522   0 19:29:27  pts/1  0:00 -ksh
    root  569522  168018   0 19:29:26      -  0:00 rlogind
 cormany  733188  409708   3 19:30:34  pts/1  0:00 ps -ef
    root  749668  168018   0   Jul 30      -  0:00 rlogind

실행중인 프로세스만 가지고는 상세한 정보를 알기가 어렵다. 기교를 조금 부려보자.
# ps -ef | grep -E "rpc|ksh" | grep -vE "grep|rpc.ttdbserver" |
   awk -v _MAX_PID=200000 '{if ($2 > _MAX_PID) {print "PID for
   process",$8,"is greater than", _MAX_PID}}'

PID for process /usr/sbin/rpc.statd is greater than 200000
PID for process /usr/sbin/rpc.lockd is greater than 200000
PID for process -ksh is greater than 200000

같은 명령어에서 파생된 결과지만 결과의 질은 달라진다. 내가 원하는 정보를 보다 효율적으로 손쉽게 접해보자.

원문 : http://www.ibm.com/developerworks/kr/library/au-spunix_clitricks/

지난 달 Part 3 에서는 grep, sed, awk 와 같은 명령행 도구의 필터들을 소개했었다. Part 4 에서는 셸 스크립트 기교에 대해서 소개한다. 셸 명령 실행, 산술연산/진법변환, 대화형 셸 스크립트의 기본이 되는 인라인 입력이나 키보드 입력, 루프 등에 대해서 다룬다. 본 셸이 기본 조건이긴 하나 배시 셸도 관계없다.

거두절미하고 아주 짧은 셸 코드 하나를 보자.
for i in ??; { mv $i $i.ppm; }

위 코드는 현재 디렉토리의 파일 이름이 정확히 2글자인 모든 파일의 확장자를 .ppm 으로 변경한다.
i는 파일이며 ??는 파일의 글자 수이다. 루프 내는 for문의 조건이 만족되는 경우 $i를 $i.ppm으로 변경하는 간단한 코드이다. 하나 더 보자.

#!/bin/sh
# baseconv: 진법을 변환하는 간단한 스크립트
#
NUMBER=1
while [ $NUMBER ]; do
    read -p "Input base: " IN
    read -p "Output base: " OUT
    read -p "Number: " NUMBER
    bc -ql <<- EOF
  obase=$OUT
  ibase=$IN
  $NUMBER
  EOF
done

위 코드는 숫자를 입력 진법에서 출력 진법으로 변환한다. 간단하다. 튜토리얼에 모두 설명된 부분.
이번 튜토리얼은 일전에 몇 번 소개되었던 셸 스크립트 관련 아티클에 비해 자세하다. 일전의 아티클을 먼저 읽어 보는 것도 좋을 것 같다. 셸 스크립트의 강력함은 말로 다 할 수 없다. 배워봅시다.~
유용한 인라인 셸 코드들도 존재하니 많은 참고가 되겠다.

원문 : http://www.ibm.com/developerworks/kr/library/tutorial/au-unixtips4/index.html


요즘 괜찮은 아티클이 많이 올라온다.
셸 스크립트. 유닉스의 꽃이라 해도 과언이 아닐 정도로 필요하고, 유용하고, 멋지다.
예전에 도스(DOS)를 이용해 본 사람이라면, 확장자가 'bat'로 되어 있는 batch 파일을 알고 있을 것이다. 스크립트라는 말에서 느낄 수 있듯, 프로그램 언어와 배치파일 사이에 있는 정도라고 이해하면 되겠다.
도스를 몰라도 상관없다. 순차적으로 어떠한 일을 해야 하는데, 그 일이 단순한 반복 작업을 계속해야 한다면, 이를 미리 정의 해 두고, 자동적으로 실행하고 싶다는 생각은 누구나 할 것이다. 비슷하다고 생각하면 이해가 쉽다.

프로그램을 조금 해 보신 분들이라면 syntax만 파악하셔도 될 것 같다. 프로그램 언어를 배우면 가장 먼저 배우게 되는 변수, 표준 입/출력/오류, 함수, if-else, case문 등의 분기분 차례로 튜토리얼이 진행되는데, 평소 셸 스크립트를 한번 공부해보고 싶었거나, 유닉스에 대해 이제 조금 뭔가 알아갈 것 같다. 하시는 분들에게 권한다.

유닉스를 만지면 언젠가는 부딪혀야 하는 셸 스크립트. 잘하든 못하든 일단 다룰 줄은 알아야 될 것이다.
그 기본이 되는 아주 기초적인 문법부터 시작하고 있으며, 생각보다 자세하다.
유의해서 보아야 할 것이 있다면 오류처리 부분. 내가 생각하는 대로 늘 스크립트가 작동할 것이라는 생각은 하지말도록 하자.
1~2시간만 시간을 투자한다면 아래 코드를 이해하고 작성할 수 있게 될 것이다.'

$vi my_second_script.ksh
#!/bin/ksh
###################################################
# 작성자: Jason Thomas
# 목적: 이 스크립트는 첫 스크립트를 개발하는 방법을 보여주기 위해 작성했다.
# 2008년 5월 1일
###################################################

# 변수 정의
HOME="/home/jthomas" # 간단한 홈 디렉터리
DATE=$(date +%H%M) # 콘 셸 명령인 date를 수행한 결과를 DATE에 저장한다.
HOSTNAME=$(hostname) # HOSTNAME은 hostname 명령을 수행한 결과를 저장한다.

##################
function if_error
##################
{
if [[ $? -ne 0 ]]; then # 함수에 전달하는 오류 코드를 점검한다.
    print "$1" # if rc > 0이면 오류 메시지를 출력하고 끝낸다.
exit $?
fi
}
if [[ -e /tmp/file ]]; then  # 먼저 파일이 존재하는지 살펴본다.
   rm -f /tmp/file # 파일 삭제
   if_error "Error: Failed removing file /tmp/file"
else
   print "/tmp/file doesn't exist"
fi

if [[ -e /tmp/test ]]; then
     mkdir /tmp/test # 디렉터리 test 생성
     if_error "Error: Failed trying to create directory /tmp/test"
else
     print "Directory exists, no need to create directory"
fi

case $TIME in
                 "2200")
                  rm -f /tmp/file1
                        ;;
                  "2300")
                  rm -f /tmp/file1
                        ;;
# 스크립트 끝
esac

결론에서도 말하고 있듯, 스크립트 헤더를 작성하고, 변수를 정의한 다음, 오류를 점검하는 순서로 배우도록 하자.
진짜, 익숙해지면 모든 작업을 스크립트로 하려고 들게 된다-_-

링크: http://www.ibm.com/developerworks/kr/library/au-kornshellscripting/

유닉스는 어렵다. 쉽지 않은 게 사실이다.
혹자는 말한다. 알고 보면 유닉스도 쉽다고? 그런데 모르는걸 어쩌나.
일단 텍스트 기반에, 명령어를 모르면 어디서 시작해야 할 지 조차 알 수가 없다.
언젠가 부터, 정말 쉬운 유닉스 강좌를 한번 해보고 싶다는 생각을 했다.
dW 연재는 튜토리얼 4편으로 나뉘며, 사용자 관점에서 기본적인 유닉스 사용법을 소개한다.
유닉스 계정만 하나 있으면 되니, 접속 할 서버가 없다면, VMWARE나 Virtual Box에 유닉스 하나 얹어놓고, 조금씩 따라 해 보자.

먼저 가장 많이 쓰는 명령어들 부터. ls, cd, pwd, mkdir, rmdir, 디렉토리 구조.
파일에 관계된 touch, cp, mv, rm,  소유권/권한에 관계된  chown, chgrp, chmod,
여러 파일을 한꺼번에 다루는 와일드 카드와 재귀(사실 별건 없다 -R 옵션으로 반복 작업을 자동화 하는 것 뿐)
압축에 관계된 tar, gzip,  파일시스템과 파일 크기에 관련된 df, du, /dev, mount, umount
입력과 출력에 관계된 stdin, stdout, redirection, cat, more, head, tail, grep, 파이프 연산자 까지.

사실 위에 것들만 다 알아도, 기본적인 유닉스 운영에는 큰 무리가 없을 정도로 중요하고 많은 비중을 차지하는 것들이다. 하지만, 조금 아쉬운 부분은, 파일시스템에 대한 설명이 조금 약하다 싶다.
윈도우 파일 시스템에 익숙해져 있는 이들이 df 명령어에 대한 간략한 설명과 다음 결과값으로, 어떻게 이해를 할 것인가.

$ df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda1             7.9G  3.7G  3.9G  50% /
none                  3.9G     0  3.9G   0% /dev/shm
/dev/sda3              24G   20G  1.9G  92% /export


/dev/sda1이 총 7.9G 이고 그 중, 3.7G를 사용하고 있고 3.9G가 남아있다는 것은 알겠다.
그런데, 대체 /dev/sda1 은 무엇인지, / 과 Mounted on은 무엇인지에 대한 설명이 없다.
파일시스템에 대한 사전지식이 없는 이들이 이해하기에는 다소 무리가 있다 싶지만, 의욕있는 분들은 알아서 검색을 통해서 난관(?)을 헤쳐가시리라 믿는다. 그래도 이해가 어렵거나, 궁금한 것이 많아서 미치겠다 하시는 분들은 메일 또는 댓글을 통해 질문을 주시면 성실히 답변을!

총 4편이 연재될 것이고 다음 편 부터는 vi나 shell을 사용하는 기교와 팁을 다룬다고 하는데,
어려워 질 수록 더 자세한 설명이 필요한 것은 당연하다. Part 1에서 아쉬웠던 부분이 좀 더 보완되었으면 하는 바램이다.

링크 : http://www.ibm.com/developerworks/kr/library/tutorial/au-dw-au-unixtips1-i.html
원문 : http://www.ibm.com/developerworks/edu/au-dw-au-unixtips1-i.html

유닉스에서 셸이란 명령줄이라고도 하는데, 운영체제 상에서 다양한 운영체제 기능과 서비스를 구현하는 인터페이스를 제공하는 프로그램이다. 사용자와 운영체제의 내부(커널) 사이의 인터페이스를 감싸는 층이라는 의미에서 셸 이라는 이름이 붙여졌다. 셸은 그 종류가 다양한데, 그 종류별로 세부적인 기능의 차이들이 조금씩 존재한다. 또한, 셸 스크립트 문법도 조금씩 다른데, 사용자 별로 자신에게 익숙한 셸이 하나씩은 있기 마련이다.

dW에서 소개하고 있는 배시(bash) 셸은 거의 모든 유닉스기반에서 활용 가능한데, 이번 튜토리얼에서는 배시 셸에 대한 간략한 역사, 주요 기능을 다루며, 유닉스 파일시스템, 디렉토리와 파일 조작방법 등을 설명하고 있다.

  • 배시 개괄
  • 배시에서 명령 행 프롬프트로 작업하기
  • 배시에서 파일과 디렉터리 다루기
  • 배시 개인화하기
  • 배시 작업 제어

이 튜토리얼을 읽기 위한 시스템 요구 사항은 없다. 단지 글을 읽고 배시를 익히면 된다. 하지만 이 튜토리얼을 최대로 활용하려면 튜토리얼이 제공하는 기법을 시도할 필요가 있다. 이렇게 하려면 버전 2.05 이상인 동작하는 배시 셸이 필요하다. 컴퓨터에 설치된 배시 셸 버전을 모른다면, 배시 셸 홈 페이지를 방문해 필요한 정보를 얻기 바란다.

원문 보기
http://www.ibm.com/developerworks/kr/library/tutorial/au-dw-au-bash-i.html

NIS(Network Information Service)는 유닉스, 리눅스 사이에서 시스템 파일 등을 NIS map 형태로 도메인에 참가하고 있는 이들끼리 공유하는 서비스이다. 방법은 NFS, automounter 등이 있다. 유닉스와 리눅스는 비슷하나, 두 시스템을 통합하는 과정을 어렵게 하는 몇 가지 중요한 차이점이 있다.
아직도 NIS가 무엇인지, NIS로 둘을 통합하는 것이 과연 어떤 의미를 지니는지 잘 모를 것이라 생각한다.

좀 더 자세히 이야기 해 보자. 최초 SUN에서 처음 개발되어 현재는 거의 모든 UNIX 시스템에서 사용되는 대표적인 통합 서비스이다. 기본 개념은 서버에 저장된 /etc 환경파일 정보를 유닉스 클라이언트들이 공유하는 서비스이다. 보통은 윈도우즈의 도메인 개념과 비슷한데, 서버에 저장된 사용자들은 클라이언트에서도 로그인 및 서비스를 이용할 수 있다는 의미가 된다.
유닉스 서버와 워크 스테이션들이 단일한 공간에 많이(10대 이상) 설치되어 있는 경우, NIS를 이용하면 편리하나, 실제로 많이 쓰이지는 않는다. 그래서 연구기관이나 학교같은 실습 장비가 많은 곳에 주로 사용되기도 한다.
이제, 조금 감이 오는지?

이러한 NIS를 이용하여, 유닉스, 리눅스간 통합에 대해서 dW에서 다루고 있다. 구조는 다음과 같다.

NIS 마스터와 슬레이브 구조

이를테면, 사용자가 암호를 변경할 때, 사용자가 NIS 데이터베이스에 직접 변경을 가하면 NIS 마스터로 변경 내역이 전해지며, 데이터베이스를 갱신하고 슬레이브 서버에 변경 내역을 전파하게 된다. NIS 데이터베이스에 변경이 일어나면 변경이 일어난 시점에서 슬레이브 서버로 자동으로 전파되며, yppush 명령을 사용하여 수동전파가 가능하다. 그럼, NIS 구성에 대해서 알아보자. NIS는 무엇보다 OS나 머신에 무관하게 파일시스템을 통해 각자의 파일과 자원을 계속 사용할 수 있다는 점이다.

자세한 내용과 구성방법 등에 대해서는 아래에서 확인하자.
http://www.ibm.com/developerworks/kr/library/au-linuxtogether/index.html

예상치 못한 종료 등의 경우로 솔라리스의 파일 시스템이 손상되었을 때, 재부팅시 "Read-only File system"이라는 에러가 발생하는 경우가 있다. 이럴 경우, 이미 마운트되어 있는 파일 시스템을 읽기/쓰기 권한으로 다시 마운트 해줘야 한다.

# umountall
# mount -F ufs -o rw,remount /

'유닉스' 카테고리의 다른 글

pkgadd 오류: admin 파일 <default>를 열 수 없습니다.  (0) 2008.11.11
SSH setting for solaris8  (0) 2008.08.26
Solaris10 sd.conf 동적으로 다시 읽기  (0) 2008.05.26
Dos Attack On UNIX  (0) 2008.05.08
디스크 Dump & Restore  (0) 2008.05.04

작년 1월 30일에 10가지 유닉스 사용습관 이라는 Article이 업데이트 된 적이 있었다.
유닉스 명령어 라인을 다루는데 있어, 효율성을 높일 수 있는 10가지 좋은 습관인데, 프로그래밍에서 변수 이름은 어떻게 명명하며, 루프구조에서는 어떤 방식이 유리하며, 가급적 전역변수는 피한다던가 하는 것과 같은 맥락에서 이해하면 되겠다. 그 10가지는 아래에 링크되어 있는데, 1년 반이 지난 지금, 10가지 더 좋은 습관에 대한 Article이 업데이트 되었다. 그 내용은 다음과 같다.

http://www.ibm.com/developerworks/kr/library/au-unixtips/
  • 파일 이름 완성 기능을 활용하자.
  • 히스토리 확장 기능을 활용하자.
  • 직전에 사용한 인수를 재사용하자.
  • pushdpopd로 디렉터리를 탐색하자.
  • 대용량 파일을 탐색하자.
  • 편집기 없이 임시 파일을 생성하자.
  • curl 명령행 유틸리티를 활용하자.
  • 정규 표현식을 적극 활용하자.
  • 현재 사용자가 누구인지 알아내자.
  • awk로 자료를 처리하자.
  • 개인적으로 awk를 종종 이용하는데, 대부분 사람들이 어렵다고 생각하여 잘 사용하지 않는다.
    awk는 텍스트를 처리하는데 아주 막강하여, 보다 높은 질의 결과물을 얻는데에 이용될 수 있다.
    참고자료를 링크한다.
    Get started with GAWK: AWK language fundamentals(06.09.19) :
    http://www.ibm.com/developerworks/edu/au-dw-au-gawk-i.html

    UNIX가 NT에 비해 강력한 많은 점들 중 하나는 무엇보다 수많은 로그 메시지들을 남긴다는 점이다.
    시스템은 언젠가 장애에 직면하게 되며, 그것에 대응하는 방법 중 가장 확실한 방법은 시스템이 남긴 로그 파일을 보는 것이다. 예를 들어, 어느날 시스템이 갑자기 패닉 상태로 떨어졌다고 하자. UNIX의 로그 파일을 살펴보면, 대부분 그 이유와 날짜, 시간이 기록되어 있다. 하지만 NT는 블루스크린이 뜨고, 곧 이어 시스템이 죽어버린다. 물론 덤프를 내리긴 하지만, 이를 분석하는 것이 무척이나 어려우며, 모든 경우에 해당되는 것 또한 아니다.
    그 외에도 UNIX는 아주 작은 부분까지도 로그파일에 메시지를 남기는데, 이 로그는 시스템을 운용하는 사람에게 무엇보다 중요하다. 하지만, 로그 파일을 이해하는 것이 그렇게 만만한 것은 아니다.

    많은 장애를 대응하다 보면, 무슨 장애의 종류가 그렇게 많은지도 모르겠다. 고객을 만나 장애를 마주하고 앉으면 가장 먼저 로그 파일을 점검하는 것이 우선이다. 그만큼 중요한 것이 로그 파일인데 대부분의 시스템 관리자들은 로그 파일을 올바로 이해하고 있지 않다. 나에게도 로그 파일의 이해를 원하는 많은 UNIX, LINUX 이용자들에게 많은 도움이 될 것 같다. Article의 일부만 발췌하면 다음과 같다.

    Listing 5. 시스템 로그 파일 예제(/var/adm/messages)
    Feb  3 16:06:58 solaris2 ata: [ID 496167 kern.info] cmdk2 at ata1 target 0 lun 0
    Feb  3 16:06:58 solaris2 genunix: [ID 936769 kern.info] cmdk2 is
                                                /pci@0,0/pci-ide@1f,1/ide@1/cmdk@0,0
    Feb  3 16:06:59 solaris2 asy: [ID 267298 kern.notice] asy0: UART @
                                              3f8 scratch register: expected 0x5a, got 0xff
    Feb  3 16:06:59 solaris2 asy: [ID 702181 kern.notice] Cannot identify UART chip at 3f8
    Feb  3 16:06:59 solaris2 asy: [ID 267298 kern.notice] asy1: UART @ 2f8 scratch register:
                                                                    expected 0x5a, got 0xff
    Feb  3 16:06:59 solaris2 asy: [ID 702181 kern.notice] Cannot identify UART chip at 2f8
    Feb  3 16:07:01 solaris2 genunix: [ID 314293 kern.info] device
              pciclass,030000@2(display#0) keeps up device sd@1,0(sd#1), but the latter is
              not power managed
    Feb  3 16:07:01 solaris2 /usr/lib/power/powerd: [ID 387247 daemon.error]
                                                                      Able to open /dev/srn
    Feb  3 16:07:08 solaris2 /sbin/dhcpagent[164]: [ID 778557 daemon.warning]
                    configure_v4_lease: no IP broadcast specified for ni0, making best guess
    Feb  3 16:07:31 solaris2 sendmail[503]: [ID 702911 mail.crit] My unqualified host name
                                                      (solaris2) unknown; sleeping for retry
    Feb  3 16:07:32 solaris2 sendmail[507]: [ID 702911 mail.crit] My unqualified host name
                                                      (solaris2) unknown; sleeping for retry
    Feb  3 16:07:48 solaris2 svc.startd[7]: [ID 652011 daemon.warning]
               svc:/system/webconsole:console: Method "/lib/svc/method/svc-webconsole start"
      failed with exit status 95.
    Feb  3 16:07:48 solaris2 svc.startd[7]: [ID 748625 daemon.error]
                 system/webconsole:console failed fatally: transitioned to maintenance
    (see 'svcs -xv' for details)
    Feb  3 16:07:55 solaris2 pseudo: [ID 129642 kern.info] pseudo-device: devinfo0
    Feb  3 16:07:55 solaris2 genunix: [ID 936769 kern.info] devinfo0 is /pseudo/devinfo@0
    Feb  3 16:08:31 solaris2 sendmail[503]: [ID 702911 mail.alert] unable to qualify
                                        my own domain name (solaris2) -- using short name
    Feb  3 16:08:32 solaris2 sendmail[507]: [ID 702911 mail.alert] unable to qualify my
                                           own domain name (solaris2) -- using short name

    대표적인 로그 파일인 messages 로그이다. 이 외에도 dmesg, syslog 등에 대해서도 언급하고 있다.
    링크 : http://www-128.ibm.com/developerworks/kr/library/au-satlogfilebasics/

    http://www.ibm.com/developerworks/kr/library/au-unix-sysadmin1.html

    유닉스 시스템을 다루다 보면, 관리자 입장에서 프로세스 정보를 얻고, 죽이고 모니터링 해야 하는 경우가 빈번하다. 일반적으로는 시스템에서 제공하는 표준 명령어로 프로세스에 대한 목록 또는 정보를 얻는데, 이렇게 얻는 정보가 원하는 형식이 아니거나 충분하지 못한 경우가 종종 발생한다. 원하는 정보를 원하는 형식으로 추출하게되면 시스템 관리는 좀 더 수월해진다. 프로세스 정보를 가독성 있게 추려내는 것은 명령어와 텍스트 기반의 유닉스 시스템에서는 상당히 중요하다. 그것은 다양한 플랫폼에서 동일한 방식으로 정보를 얻어내는 방법인 표준화 기법 또한 소개하고 있다.

    BSD/SVR4 유닉스 계열에서 사용자/전체 프로세스 목록 보기, 열 지정하기, CPU사용량 추적하기, 여러 프로세스에 시그널 보내기, 명령 하나로 여러 프로세스 죽이기, 메모리 사용량 계산하기, 백그라운드에서 프로세스 안전하게 실행하기 등 많은 기법에 대해 소개하고 있다. 실제로 고객을 대하고 시스템을 점검하면, 갖가지 요구사항들이 끝없이 쏟아진다.

    Listing 14. psawk로 메모리 사용량 계산하기

    $ ps -A -o rss,vsz,command|grep bash | \
         awk '{rss += $1; vsz += $2 } END { print "Real: ",rss, "Virtual: ",vsz }'
    Real:  4004 Virtual:  305624

    위는 bash 프로세스가 사용하는 물리적 메모리 양과 가상 메모리 양을 합한 결과로 메모리 사용량 문제와 스왑 공간 사용량 문제를 진단할 때 특히 유용하다. 이 외에도 프로세스에 관련하여 갖가지 기법들을 소개하고 있다.

    http://www.ibm.com/developerworks/kr/library/au-unix-sysadmin1.html